我想用两个线程添加两个数字,但我不明白我错在哪里 我的输出是错误的。我知道问题是同步但不能解决。
git fetch
输出:
import java.io.*;
class GFG {
public static void main (String[] args) throws InterruptedException {
final Addition a=new Addition();
Thread t1 = new Thread(new Runnable()
{
public void run(){
try {
a.add(1,10);
} catch(Exception e) {
}
}
});
Thread t2 = new Thread(new Runnable()
{
public void run(){
try {
a.add(1,4);
} catch(Exception e) {
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
public static class Addition{
int a, b;
int sum=0;
public void add(int a, int b) throws InterruptedException{
synchronized(this){
for (int i=a;i<=b;i++){
sum=sum+i;
Thread.sleep(1000);
}
System.out.println("Sum="+sum);
}
}
}
}
通过查看输出我可以说......在完成THREAD t1的任务后,THREAD t2将其结果添加到t1 ...... ??
答案 0 :(得分:0)
这是由某人设计的故意误导(也许它属于谜题溢出?)。缩进与大括号不匹配。
你可以说“sum”只会初始化为零一次并且永远不会重新初始化为零,因为Addition只构造一次(new Addition只发生一次)。
如果您希望Addition对象独立工作,请在synchronized内部将some设置为零。
我有点讨厌我回答这个,因为它显然是一个构造的拼图/家庭作业类型的东西,但你可以把这个作为免费赠品我想
答案 1 :(得分:0)
实际问题 - 除了代码显然是故意误导 - 是sum
是Addition
的类成员。当您在两个线程中使用相同的Addition
实例时,sum的状态在线程之间共享。这是第二个线程不会开始与0
总结,而是与前一个加法55
的结果相加。这导致观察到的输出。
如果您将Addition
更改为以下程序,程序将按预期运行。
public static class Addition {
int a, b;
public void add(int a, int b) throws InterruptedException {
int sum = 0;
synchronized (this) {
for (int i = a; i <= b; i++) {
sum = sum + i;
Thread.sleep(1000);
}
System.out.println("Sum=" + sum);
}
}
}
答案 2 :(得分:0)
您使用的是Addition: "a"
的同一个实例,虽然Addition's
全局变量"a" and "b"
已被隐藏,但"sum"
未被隐藏。
答案 3 :(得分:0)
Addition
的实例。Addition
的唯一实例具有变量sum
,它在线程t1和t2之间共享。sum
的值,并且结果已合并。我运行了你的程序并进行了一些更改以添加日志,如你所见:
public static class Addition{
int a, b;
private int sum=0;
public void add(int a, int b, int id) throws InterruptedException{
System.out.println("INIT ADD t:[" + id + "]");
synchronized(this){
for (int i=a;i<=b;i++){
System.out.println("Sum Before t:[" + id + "] i:[" + i + "]=" + sum);
sum=sum + i;
System.out.println("Sum After t:[" + id + "] i:[" + i + "]=" + sum);
Thread.sleep(1000);
}
}
System.out.println("Sum t:[" + id + "]=" + sum);
}
}
日志证实我告诉过你,每次踏板都会影响变量和。日志:
INIT ADD t:[1]
Sum Before t:[1] i:[1]=0
INIT ADD t:[2]
Sum After t:[1] i:[1]=1
Sum Before t:[1] i:[2]=1
Sum After t:[1] i:[2]=3
Sum Before t:[1] i:[3]=3
Sum After t:[1] i:[3]=6
Sum Before t:[1] i:[4]=6
Sum After t:[1] i:[4]=10
Sum Before t:[1] i:[5]=10
Sum After t:[1] i:[5]=15
Sum Before t:[1] i:[6]=15
Sum After t:[1] i:[6]=21
Sum Before t:[1] i:[7]=21
Sum After t:[1] i:[7]=28
Sum Before t:[1] i:[8]=28
Sum After t:[1] i:[8]=36
Sum Before t:[1] i:[9]=36
Sum After t:[1] i:[9]=45
Sum Before t:[1] i:[10]=45
Sum After t:[1] i:[10]=55
Sum t:[1]=55
Sum Before t:[2] i:[1]=55
Sum After t:[2] i:[1]=56
Sum Before t:[2] i:[2]=56
Sum After t:[2] i:[2]=58
Sum Before t:[2] i:[3]=58
Sum After t:[2] i:[3]=61
Sum Before t:[2] i:[4]=61
Sum After t:[2] i:[4]=65
Sum t:[2]=65
在您同步for
阻止时,第二个线程(t2
)开始添加结果并将结果存储到sum
,但sum
的结果为{{1} ()在t1
的开头。
所以,根据这个日志,你想要获得什么样的行为?