JavaN线程更新值

JavaN线程更新值,java,multithreading,java-threads,Java,Multithreading,Java Threads,我试图同时运行n个线程。每个线程应该对不同的数组求和并更新全局值 遗憾的是,全局值更新不正确 我不想使用thread.join() 这是我目前的代码: public class myClass { private static class Values { private static double sum; public synchronized static void add(double dd) { sum += dd; }; public

我试图同时运行n个线程。每个线程应该对不同的数组求和并更新全局值

遗憾的是,全局值更新不正确

我不想使用thread.join()

这是我目前的代码:

public class myClass {
private static class Values {
    private static double sum;

    public synchronized static void add(double dd) {
        sum += dd;
    };
    public synchronized double get() {
        return sum;
    }
}


public static double CreateThreads(double[] array) {
    final Values values = new Values();

    ...
    ...
    ...


    Thread[] threads = new Thread[nOP];

    for (int i = 0; i<threads.length; i++) {


        threads[i] = new Thread(new Runnable() {

            public void run() {

                    Values.add(sum(tab));

            }

        });
        threads[i].start();

    }

    return values.get();
}

public static void main(String[] args) throws IOException {
    double[] arr = createArray(4);
    double sumLogg = CreateThreads(arr);

    System.out.println("\n\nSum: " + sumLogg);      
}
公共类myClass{
私有静态类值{
私有静态双和;
公共同步静态无效添加(双dd){
sum+=dd;
};
公共同步双get(){
回报金额;
}
}
公共静态双CreateThreads(双[]数组){
最终值=新值();
...
...
...
线程[]线程=新线程[nOP];

对于代码中的(int i=0;i,您正在使用
threads[i].start();
启动线程,但您从未等待它们通过
.join()
调用完成执行。这可能会导致您的方法在所有线程完成执行之前返回一个值,从而导致返回一个不正确的值

要修复此问题,请在返回值之前添加类似的内容:

for(Thread t : threads) {
    t.join();
}

如果不想使用Thread.join,可以使用CountDountLatch:

    CountDownLatch cdl = new CountDownLatch(nOP);
    Thread[] threads = new Thread[nOP];
    for (int i = 0; i<threads.length; i++) {
        threads[i] = new Thread(new Runnable() {
            public void run() {
                values.add(sum(tab));
                cdl.countDown();
            }
        });
        threads[i].start();
    }
    cdl.await();
CountDownLatch cdl=新的CountDownLatch(nOP);
线程[]线程=新线程[nOP];

对于(int i=0;我不想使用join(),不知道OP为什么说他不想使用join。等待线程结束是一种很好的方法。@Teddy使用join()是最有效的解决方案,如果您想保留“打印答案”在所有线程完成求和之前,是的,join可以工作。我不知道是否还有其他好方法。也许你可以在一个循环中等待,直到完成操作的线程数等于总线程数。检查ExecutorService.ShutdowNow的工作方式可能会很有趣。也许他们使用倒计时闩锁?嗯,我知道我没有注意到你不想使用
.join()
,为什么?除了你得到的答案:你没有在同一个锁上同步读写:一个在Values.class上同步,另一个在CreateThreads方法中创建的Values实例上同步(这违反了命名约定,顺便说一句)。如果您不理解静态字段和实例字段之间的区别,那么在使用threads.Values.get之前,您应该了解这一点。但是您正在创建Values类的实例。@ruan要么全部使用静态字段,要么全部使用单个实例。如果您不想使用
连接
,则必须使用其他方法来连接它让线程完成(例如,
CountDownLatch
Semaphore
ForkJoinTask
,…)。您现在这样做的方式可能是在任何线程有机会运行之前读取结果。为什么
sum
add()
是静态的?