使用两个线程添加两个数字

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 类型的东西,但我想你可以把它作为免费赠品

实际的问题——除了代码明显是故意误导之外——是 sumAddition 的 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.

的开头

那么,根据这个日志,你想要得到的行为是什么?