drunkmonkey
drunkmonkey

Reputation: 1181

Using more than one thread in Java

I'm new to concurrent programing and have been working on code which has a queue of items to be processed, this is passed to some worker threads, the number specified by the user. At the moment I've just tried to do it with two worker threads plus the main.

private static class workerThread extends Thread {

        workerThread(){
            super();
        }


        public void run(){
             while (!workQueue.isEmpty()) {

            String x = workQueue.remove();
            //System.out.println("work queue size: " + workQueue.size());
            Vector<String> list2 = new Vector<String>((Vector) table.get(x));
            list2 = process(x, list2);
            //System.out.println(list2 + "list2");
            table.put(x, list2);

            //System.out.println(x + "key" + "value" + vvv);

        }

        }

That's the thread workerthread class, I've tried to call it just by creating two new threads:

workerThread wt = new workerThread();
    workerThread wt2 = new workerThread();
    wt.start();
    wt2.start();
    try {
        wt.join();
        wt2.join();
    } catch (InterruptedException ex) {
        Logger.getLogger(includeCrawler.class.getName()).log(Level.SEVERE, null, ex);
    }

I'm not sure if this is right, or will have any benfit due to waiting for the joins? Thanks for any help.

Upvotes: 3

Views: 1679

Answers (3)

loscuropresagio
loscuropresagio

Reputation: 1952

You definitely have to use Executors. This is an example just for reference. It works on a single thread, but I think it's a good start for you. It's easily adaptable to an arbitrary number of threads.

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<MyObject> f =
    executor.submit(new Callable<MyObject>() {

      @Override
      public MyObject call() throws Exception {
        MyObject obj = new MyObject();
        // do stuff
        return obj;
      }

    });

MyObject myObject =
    new MyObject();

try {
  myObject = f.get(500, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
  // stuff
}
catch (ExecutionException e) {
  // stuff
}
catch (TimeoutException e) {
  // stuff
}
finally {
  executor.shutdown();
}

In this case I wanted to wait at most 500ms before timeout, but this is optional. Hope this could help.

Upvotes: 0

Johannes
Johannes

Reputation: 2121

Just a few references, I think you want to use a BlockingQueue along with an ExecutorService and a Runnable or Callable.

final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); perhaps even an instance variable (private static final ExecutorService POOL = ...). For an I/O bound application you might want to use more threads than the available processors. Then again you don't want to use Vector. Use another List implementation (usually ArrayList is the one to use).

BTW: If you want to master concurrent programming you might also want to read about Akka and Actors/STM instead of using the usual shared mutability model.

Edit: I would definately recommend http://pragprog.com/book/vspcon/programming-concurrency-on-the-jvm and Effective Java from Josh(ua) Bloch.

Upvotes: 0

Michael Borgwardt
Michael Borgwardt

Reputation: 346327

A much cleaner and scalable way to do this is to use a thread pool created by the Executors class.

By the way, the Vector class is obsolete and should not be used anymore - use ArrayList instead and dump whatever book or tutorial where you learned to use Vector - it's more than a decade out of date.

Upvotes: 1

Related Questions