我希望在5个线程完成后从WorkerThread类中获取所有计数。计数器是否按预期方式工作?谢谢。在WorkerThread构造函数中,似乎每个计数器都成为每个线程的一个变量,而不是在5个线程之间共享。
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;
}
}
答案 0 :(得分:1)
同步似乎对我来说是正确的。如果计数是您唯一的任务,您可以跳过Counter类并直接使用AtomicInteger来消除复杂性。 (如果您想要实现需要正确同步的共享状态对象的更复杂的任务,请保留它。)
不要打电话给你的工人班&#34;线程&#34;。它不是一个线程,它是一个由线程执行的任务。
最后但并非最不重要的是,您的关机代码存在问题。请注意,关闭不会阻止,但会立即返回。因此,您过早地评估计数器。
以下代码修复了所有这些问题:
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
}
}
有关如何正确关闭ExecutorService
的详细信息,请参阅http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html,“使用示例”部分&#39;。