JavaN线程更新值
我试图同时运行n个线程。每个线程应该对不同的数组求和并更新全局值 遗憾的是,全局值更新不正确 我不想使用thread.join() 这是我目前的代码: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
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()
是静态的?