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

时间:2017-11-15 19:39:33

标签: java multithreading addition

  

我想用两个线程添加两个数字,但我不明白我错在哪里    我的输出是错误的。我知道问题是同步但不能解决。

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 ...... ??

4 个答案:

答案 0 :(得分:0)

这是由某人设计的故意误导(也许它属于谜题溢出?)。缩进与大括号不匹配。

你可以说“sum”只会初始化为零一次并且永远不会重新初始化为零,因为Addition只构造一次(new Addition只发生一次)。

如果您希望Addition对象独立工作,请在synchronized内部将some设置为零。

我有点讨厌我回答这个,因为它显然是一个构造的拼图/家庭作业类型的东西,但你可以把这个作为免费赠品我想

答案 1 :(得分:0)

实际问题 - 除了代码显然是故意误导 - 是sumAddition的类成员。当您在两个线程中使用相同的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的开头。

所以,根据这个日志,你想要获得什么样的行为?