2012-06-21 3 views
5

次のコードはどうなりますか?同期は機能しますか?これはインタビューの質問です。Javaで同期変数を再割り当てするとどうなりますか?

class T 
{ 
    public static void main(String args[]) 
    { 
     Object myObject = new Object(); 
     synchronized (myObject) 
     { 
      myObject = new Object(); 
     } // end sync 
    } 
} 
+4

同期ブロックがメインにあり、ループ内ではなく、一度だけ実行されます。ここで同期のポイントはありません(別のメインからメインを呼び出す場合を除き、これは変です)。 – assylias

答えて

4

同期ブロックを入力するたびに、別のオブジェクトで同期します。ほとんどの場合、これはあなたを混乱させること以外は何もしませんが、2つのスレッドが同じオブジェクトを見て待つという小さなチャンスがあります。

final以外のフィールドで同期している場合は、このため、コードアナライザーによって警告が表示されます。

1

は、それはまだ取得したのと同じモニターを解放するだけでなく、(それは基本的に無意味な同期を行う、ローカル変数だとして、ここでは不可能)myObjectを使用してロックし、他のコードでは、新しいオブジェクトを使用することを開始します。

同期がオブジェクト(またはオブジェクトに関連付けられたモニタ)に適用されていることを忘れないでください。変数ではありません。獲得/解放されるモニターは、同期ブロックの開始に達したときの式の値にのみ依存します。式はではなく、で、同期ブロックの最後に再評価されます。

0

いいえ、動作しません。新しいスレッドが到着するたびに、新しいmyObjectが作成されます。特に、myObjectはローカル変数です。

ロックしているオブジェクトを変更するため、myObjectがクラスメンバーであっても機能しません。詳しい説明はsynchronization of non-final fieldに関する質問を参照してください。

0

オブジェクトがスレッドによって共有されていないため、このコードの背後にある理由はわかりません。同期ブロックを削除しても、実際の結果には何の影響も与えません。コードを速く実行するだけです

0

myObjectのロックを取得する必要があります。このロックがブロックされている場合、ロックが解除されるまで待つ必要があります。

同期にはマルチスレッド環境が必要です。しかし、あなたのコードはconcurrentとは関係ありません。何も起こらないことを申し訳なく思っています。

0

コードを実行し、結果を分析します。

public class Test { 
    static Foo o = new Foo(0); 
    static class Foo { 
     private int i = 0; 
     Foo(int i) { 
      this.i = i; 
     } 
     public void addOnce() { 
      this.i++; 
     } 
     public String toString() { 
      return String.valueOf(i); 
     } 
    } 
    public static void main(String args[]) { 
     test1(); 
     try {Thread.sleep(10000);} catch (Exception e) {} 
     test2(); 
    } 
    public static void test1() { 
     Runnable r = new Runnable() { 
      public void run() { 
       synchronized (o) { 
        System.out.println("1------>"+o); 
        o = new Foo(1); 
        try {Thread.sleep(3000);} catch (Exception e) {} 
        System.out.println("1------>"+o); 
       } 
      } 
     }; 
     new Thread(r).start(); 
     new Thread(r).start(); 
    } 
    public static void test2() { 
     Runnable r = new Runnable() { 
      public void run() { 
       synchronized (o) { 
        System.out.println("2------>"+o); 
        o.addOnce(); 
        try {Thread.sleep(3000);} catch (Exception e) {} 
        System.out.println("2------>"+o); 
       } 
      } 
     }; 
     new Thread(r).start(); 
     new Thread(r).start(); 
    } 
} 
関連する問題