使用两个线程添加两个数字
Adding Two Numbers using Two Threads
I want to add just two numbers using two threads,but i didn't understand where i am wrong.
My output is wrong.And i know problem is with synchronized but not able solve.
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);
}
}
}
}
输出:
Sum=55
Sum=65
通过查看输出,我可以说...完成 THREAD t1 的任务后,THREAD t2 正在将其结果添加到 t1...??
这是有人故意误导而设计的(也许它属于 puzzles overflow?)。缩进与大括号不匹配。
你可以看出 "sum" 只会被初始化为零一次并且永远不会重新初始化为零,因为加法只构造一次(新加法只发生一次)。
如果您希望Addition 对象独立工作,请在synchronized 中将some 设置为零。
我有点讨厌我回答这个问题,因为它显然是一种构造的 puzzle/homework 类型的东西,但我想你可以把它作为免费赠品
实际的问题——除了代码明显是故意误导之外——是 sum
是 Addition
的 class 成员。当您在两个线程中使用相同的 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);
}
}
}
您使用的是 Addition: "a"
的同一个实例,虽然 Addition's
全局变量 "a" and "b"
是隐藏的,但 "sum"
不是。
- 两个线程使用同一个实例 class
Addition
.
- class
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);
}
}
日志证实了我告诉过你的,变量 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
的结果是 t1
(55) 在 for
.
的开头
那么,根据这个日志,你想要得到的行为是什么?
I want to add just two numbers using two threads,but i didn't understand where i am wrong.
My output is wrong.And i know problem is with synchronized but not able solve.
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);
}
}
}
}
输出:
Sum=55
Sum=65
通过查看输出,我可以说...完成 THREAD t1 的任务后,THREAD t2 正在将其结果添加到 t1...??
这是有人故意误导而设计的(也许它属于 puzzles overflow?)。缩进与大括号不匹配。
你可以看出 "sum" 只会被初始化为零一次并且永远不会重新初始化为零,因为加法只构造一次(新加法只发生一次)。
如果您希望Addition 对象独立工作,请在synchronized 中将some 设置为零。
我有点讨厌我回答这个问题,因为它显然是一种构造的 puzzle/homework 类型的东西,但我想你可以把它作为免费赠品
实际的问题——除了代码明显是故意误导之外——是 sum
是 Addition
的 class 成员。当您在两个线程中使用相同的 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);
}
}
}
您使用的是 Addition: "a"
的同一个实例,虽然 Addition's
全局变量 "a" and "b"
是隐藏的,但 "sum"
不是。
- 两个线程使用同一个实例 class
Addition
. - class
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);
}
}
日志证实了我告诉过你的,变量 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
的结果是 t1
(55) 在 for
.
那么,根据这个日志,你想要得到的行为是什么?