2017-11-15 18 views
-1

2つのスレッドを使用して2つの数値を追加したいが、どこが間違っているのか分からなかった。
私の出力は間違っています。私は問題が同期されていますが、解決できないことを知っています。2つのスレッドを使用して2つの数値を加算する

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 

と出力を見て、私はそれを言うことができます...スレッドT1のタスクを完了した後、スレッドT2はT1にその結果を追加して...? ?

+0

両方のスレッドで 'a'を使用しています... –

+2

取得したいものを理解するには、t1とt2から期待している最終結果は何ですか? –

+0

あなたの意図する結果は何ですか? – brummfondel

答えて

0

実際の問題を推測するの景品として、このいずれかを持つことができますので、私はこれに答えていること嫌い - コードは明らかに誤解されて横にいること目的は - sumAdditionのクラスメンバーです。両方のスレッドで同じAdditionのインスタンスを使用しているので、合計状態はスレッド間で共有されます。つまり、2番目のスレッドは、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); 
    } 
    } 
} 
+0

私は理解しています...しかし、なぜ我々は最終的なintとして "a"と "b"を作っているのですか? –

+0

メソッドのパラメータを意味しますか?誤って入力パラメータを上書きしないように、パラメータを最終的にすることをお勧めします。あなたの例では、ファイナルは効果がありません。注意すべき唯一の重要なことは、メソッドのパラメータがクラスのメンバ 'a'と' b'をシャドーイングしていることです。あなたの例では使用されていないので、実際にクラスメンバを削除することができます。実際には私のIDEによって自動的に 'final'が追加されました。私は上記の例から削除しました... – dpr

+0

はい、あなたは正しいです!ここでクラスメンバーの使用はありません...理解しました..ありがとう.. –

0

これは意図的に誤解を招くように設計されました(おそらく、パズルがオーバーフローしているのでしょうか?)。インデントが中括弧に一致しません。

「加算」は一度ゼロに初期化され、一度もゼロに再初期化されないことがわかります。

Additionオブジェクトを独立して機能させたい場合は、synchronized内でsomeをゼロに設定します。

私はちょっとそれが明らかなものの構築パズル/宿題のタイプですが、あなたは私が

+0

これはなぜ/どのようにこの場合の動作に影響を及ぼしますか? –

+0

実際には、加算は一度だけインスタンス化されるため、合計は一度ゼロに設定されます。答えを明らかにする。 –

0

あなたはAddition: "a"の同じインスタンスを使用していて、隠されたが、"sum""a" and "b"Addition'sグローバル変数はありませんが。

0
  • 2つのスレッドは、クラスAdditionの同じインスタンスを使用します。
  • クラスAdditionの一意のインスタンスには、スレッドt1とt2の間で共有される変数sumがあります。
  • それぞれのスレッドが実行されているので、値は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); 
    } 

    } 

ログは、私は、変数の和が各トレッドずつ影響を受けている、あなたに言ったことを確認。ここでは、ログ:あなたがforブロックを同期化したよう

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 

は、第二のスレッド(t2)はsumに結果を追加し、保存するために開始しますが、forの始まりでt1(55)の結果をsumています。

このログによれば、取得したい動作は何ですか?

+0

これを解決するにはどうしたら 'static'を削除しますか?これは何の効果もありません。 – dpr

+0

@drp、私はあなたに私に尋ねる情報を追加します。ありがとう。しかし、私はユーザーが何をしたいか分からない。 –

+0

提案した変更を試しましたか? 'sum'がスレッド間で共有されるので、クラスが「静的」であるか否かにかかわらず、何の効果もないとは思えません。 – dpr