计算多个线程中的单个变量

时间:2011-04-06 12:27:22

标签: java multithreading thread-safety runnable

我有以下可运行的类。

public class OnesRun implements Runnable {

    public int ones = 0;

    private int passendNumber;

    public OnesRun(int passendNumber) {
        this.passendNumber = passendNumber;
    }

    public void run() {
        if (passendNumber == 1)
            ones++;
    }

}

此类的每个实例都应该增加ones的值,如果它遇到一个。

执行完所有线程后,我想从课堂外读取ones的值。

  1. 如何增加ones 线程安全吗?
  2. 我如何访问 来自本课外的ones? 通过静态变量?或者我可以将它放入应用程序中 上下文?

  3. 修改

    我希望以下伪代码能让我的意图更清晰。

    OnesRun.ones = getCurrentValueOnes();
    
    while ( (number = readNumbersFromFile) != null) {
       threadPool.execute(new OnesRun(number));
    }
    
    print("Overall values of ones " + OnesRun.ones);
    

2 个答案:

答案 0 :(得分:7)

  

如何增加线程安全?

您可以使用AtomicInteger

  

如何从本课外访问?通过静态变量?或者我可以将它放入应用程序上下文中吗?

您可以使用简单的吸气剂。或者我错过了什么?

更新

根据您的更新,以下是我修改代码示例的方法:

public class OnesRun implements Runnable {

    private static final AtomicInteger ones = new AtomicInteger();

    private final int passendNumber;

    public OnesRun(int passendNumber) {
        this.passendNumber = passendNumber;
    }

    public void run() {
        if (passendNumber == 1)
            OnesRun.ones.incrementAndGet();
    }

    public static void setOnes(int newValue) {
        ones.set(newValue);
    }

    public static int getOnes() {
        return ones.get()
    }
}

...

OnesRun.setOnes(getCurrentValueOnes());

while ( (number = readNumbersFromFile) != null) {
   threadPool.execute(new OnesRun(number));
}

print("Overall values of ones " + OnesRun.getOnes());

除了已经讨论的内容(使ones成为private static AtomicInteger并添加一个getter / setter对),我创建了两个成员final,如果可能的话,这总是可取的,尤其是并发代码。

另请注意,AtomicInteger作为实现细节保留 - 它不会被类的公共接口公开。

答案 1 :(得分:0)

使用AtomicInteger(线程安全)和静态属性。

public class OnesRun implements Runnable {
    private static final AtomicInteger ones = new AtomicInteger();

    private int passendNumber;

    public OnesRun(int passendNumber) {
        this.passendNumber = passendNumber;
    }

    public void run() {
        if (passendNumber == 1) {
            ones.incrementAndGet();
        }
    }

    public static AtomicInteger getOnes() {
        return ones;
    }
}


OnesRun.getOnes().set(getCurrentValueOnes());

while ( (number = readNumbersFromFile) != null) {
    threadPool.execute(new OnesRun(number));
}

print("Overall values of ones " + OnesRun.getOnes().get());