这是计算多线程的正确方法吗?

时间:2014-03-17 20:41:32

标签: java multithreading

我希望在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;
    }
}

1 个答案:

答案 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;。