Java 在多个线程中计算单个变量

Java 在多个线程中计算单个变量,java,multithreading,thread-safety,runnable,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 (passendNumb

我有以下可运行的类

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++;
    }

}
该类的每个实例在遇到1时都应该增加1的值

执行完所有线程后,我想从类外部读取线程的值

我怎样才能增加一个呢 线程安全? 我如何访问 这门课以外的? 通过一个静态变量?或者我可以把它放到应用程序中吗 上下文 编辑:

我希望下面的伪代码能让我的意图更加清晰

OnesRun.ones = getCurrentValueOnes();

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

print("Overall values of ones " + OnesRun.ones);
如何增加线程安全性

你可以使用

我怎样才能从这个类之外访问这些?通过一个静态变量?或者我可以把它放到应用程序上下文中吗

您可以使用一个简单的getter。还是我遗漏了什么

使现代化 根据您的更新,以下是我将如何修改您的代码示例:

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());
除了已经讨论过的将一个成员设置为私有静态AtomicInteger并添加一个getter/setter对之外,我将两个成员都设置为final,如果可能的话,这总是可取的,尤其是在并发代码中


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

使用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());

另外,将getter设置为private而不是public以强制使用getter。但是在所有线程完成后,我必须创建这个类的新实例并调用getter,不是吗?@Bernhard V,如果您想在每个OnesRun实例之间共享getter,请使用静态getter将其设置为静态。我已经编辑了我的问题。我希望这有助于您理解我。请注意,伪代码很可能会执行您想要的操作,因为打印的值将介于0和实际数之间。原因是您无法确保在访问计数之前,所有OnesRun实例都已执行。没错。我将不得不等到所有线程都执行完毕。