Reputation: 1675
I would like to get all counts from WorkerThread class after the 5 threads finished. Does the Counter work the way as expected? Thanks. In the WorkerThread constructor, it seems each counter becomes one variable of each thread, not shared among the 5 threads.
public class Test {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
Counter counter = new Counter();
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread(String.valueOf(i), counter);
executor.execute(worker);
}
executor.shutdown();
System.out.println("Total Count: " + counter.value());
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
}
}
class Counter{
private AtomicInteger count;
public Counter(){
count = new AtomicInteger();
}
public int increment(){
return count.incrementAndGet();
}
public int value(){
return count.get();
}
}
class WorkerThread implements Runnable {
private String command;
private Counter c;
public WorkerThread(String s, Counter c){
this.command=s;
this.c = c;
}
@Override
public void run() {
for(int i=0; i<6; i++){
c.increment();
}
processCommand();
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString(){
return this.command;
}
}
Upvotes: 1
Views: 116
Reputation: 24454
Synchronization seems correct to me. If counting is your only task, you could skip the Counter class and directly use AtomicInteger to remove complexity. (Keep it if you want to realize more complex tasks which require a proper synchronized shared state object).
Don't call your worker class "Thread". It is not a thread, it is a task that is executed by a thread.
Last but not least, there's something wrong with your shutdown-code. Note that shutdown does not block but return immediately. So you're evaluating your counter too early.
The following code fixes all of this issues:
public class Test {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
AtomicInteger counter = new AtomicInteger();
for (int i = 0; i < 10; i++) {
executor.execute(new Worker(counter));
}
executor.shutdown();
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
// executor does not shut down.
// try executor.shutdownNow() etc.
}
System.out.println("Total Count: " + counter.get());
}
}
class Worker implements Runnable {
private final AtomicInteger counter;
public Worker(AtomicInteger counter) {
this.counter = counter;
}
public void run() {
// do something
counter.incrementAndGet();
// do something else
}
}
For more information about how to correctly shutdown an ExecutorService
, see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html, section 'Usage Examples'.
Upvotes: 1