2010-12-16 15 views
0

次のコードは正しいバランス(100)を表示しないでくださいが、毎回100をプリントアウトしています。何故ですか?次のコードはスレッドセーフではないようです。Javaスレッディングの質問

public class ThreadObject implements Runnable{ 

    private int balance; 

    public ThreadObject() { 
     super(); 
    } 

    public void add() { 
     int i = balance; 
     balance = i + 1; 
    } 

    public void run() {  
     for(int i=0;i<50;i++) { 
      add(); 
      System.out.println("balance is " + balance); 
     } 
    } 

} 

public class ThreadMain { 

    public static void main(String[] args) { 

     ThreadObject to1 = new ThreadObject(); 
     Thread t1 = new Thread(to1); 
     Thread t2 = new Thread(to1); 
     t1.start(); 
     t2.start(); 

    } 
} 

次のコードが本当にスレッドセーフであれば、どのように説明できますか?

add()のコードはスレッドセーフではないようです。 1つのスレッドが現在balanceiを設定している可能性がありますが、2番目のスレッドが引き継ぎながらbalanceを更新している間は非アクティブになります。その後、スレッド1が目覚めて、balanceを廃止に設定すると、iと1が加算されます。

答えて

1

printlnは、天びんを更新するコードよりも何千も遅いです。各スレッドはほぼすべての時間印刷を費やしているため、同時にバランスを更新する可能性は非常に低くなります。

iを読み、i + 1を書き込む間に小さな睡眠を追加します。

上記のコードを実行した後にできるだけ小さい値iはありますか?

+0

は最小値50ですか? 私が考えることができるWORSTのケースは、T1がスリープ状態になるため、T2が引き継ぎ、T1が起き上がり、バランスが更新され、T2が起き上がり、バランスを更新します。 それよりも悪いケースがありますか? – Glide

+0

@グライド:いいえ、ずっと少ないです。 –

+0

私は理解できないようです。あなたは説明できますか? – Glide

0

あなたのprintlnを少し上に移動して、スレッドセーフではないことを確認してください。あなたがまだ変更を見ることができない場合は、(5000以上のように)50を大きくしてください。

public void add() { 
    int i = balance; 
    System.out.println("balance is " + balance); 
    balance = i + 1; 
} 

public void run() {  
    for(int i=0;i<50;i++) { 
     add(); 
    } 
}