Reputation: 1181
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
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
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
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