我的程序有问题。总和数据在多个线程之间共享。它应该在每个线程添加后给出总和。
public class ThreadPractise implements Runnable
{
Integer num;
String name;
volatile Integer commonSum;
Object lock;
public ThreadPractise(Integer i,String threadName ,Integer sum, Object sharedLock) {
num = i;
name = threadName;
commonSum =sum;
lock = sharedLock;
}
@Override
public void run() {
Integer cube = calculate(num);
update(cube);
System.out.println(Thread.currentThread().getName()+" has commonSum after update as "+commonSum);
}
public void update(Integer cube) {
synchronized (lock) {
this.commonSum = this.commonSum + cube;
System.out.println(Thread.currentThread().getName()+" has commonSum as "+commonSum);
}
}
public int calculate(Integer num2) {
return (num2*num2*num2);
}
public static void main(String[] args) {
Integer sum = new Integer(0);
Object lock = new Object();
for(int i=1;i<=3;i++)
{
Thread t = new Thread(new ThreadPractise(i, "Thread"+i, sum,lock));
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Sum of 1^3+2^3+3^3 = "+sum);
}
}
但是总和始终为 0。当我更改为 AtomicInteger 时,它可以工作,但我需要解决此实现的问题。另外请告诉我我所做的线程锁定是否正确。
最佳答案
您的问题与并发无关。查看您的 main
方法。它有一个局部变量sum
。该局部变量永远不会更新。相反,您正在更改 ThreadPractise
实例的 num
字段引用的对象。该值使用 sum
的值进行初始化,但一旦替换 num
的值,其值就不再与 sum
相关,因为值只是被替换但不更新。因此,打印的值仍然是 0
,它是最初分配给 sum
的值。
简单地说,您所做的就是:
Integer a = 0;
Integer b = a;
b = 1; // does not change a
System.out.println(a); // prints '0'
但在 Java 中,如果不为变量分配新值,则无法更改该变量引用的值。
相反,使用AtomicInteger
,您将一个可变实例传递给您的线程。您现在不是替换 num
引用的值,而是更新该实例所代表的值。这样,num
和 sum
变量就保持相同,因为它们引用相同的对象。对于不可变的Integer
来说,这种方法是不可能的。如果 Integer
类有一个类似 setValue(int)
的方法,那么您所做的将与 sum
和 num
一样工作同样会引用同一个对象。
关于java - 线程之间共享数据不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26968625/