[英]Shared data between threads not right
我的程序有问题。 和数据在多个线程之间共享。 它应该在每个Thread添加到它之后给出总和。
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
会同样引用同一个对象。
Integer
是不可变的。 您不能将Integer
传递给方法,并期望以这种方式获得更新版本。
如果您不想使用AtomicInteger
(可更新,甚至以线程安全的方式,这将是我的首选解决方案),您需要从每个线程检索部分总和或让线程更新公共累加器某处(例如通过使commonSum
静态)。
Integer
对象是不可变的。 虽然Thread
中存在的Integer
实例最初与您在main方法中声明的实例相同,但每次其值更改时,它都会替换为新实例,即每次添加到commonSum
。 所有线程都将保存对不同Integer
对象的引用,并且main方法中的实例将不受影响。
您必须将Integer
包装到某种对象中,以便能够在main方法和线程之间共享它。 AtomicInteger
就是这样做的,作为额外的奖励,它将为您完成所有同步。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.