2013-01-21 12 views
17

javaのモニターはインスタンス変数へのアクセスを制限していないのですか?synchronizedステートメントで宣言されたメソッドまたはsynchronizedステートメントのコードにのみアクセスできますか?javaモニタにインスタンス変数が含まれていますか?

私はthread ythread rが同期宣言されていないUNSYNCメソッドを呼び出している間同期宣言された同期メソッドを呼び出し、二つのスレッドを作成しました。どちらも共有オブジェクトsのメソッドを呼び出します。

Thread rは、オブジェクトsのインスタンス変数を、そのオブジェクトのモニタまたはロックがまだthread yによって保持されている間に変更することができます。

Javaのモニタは、インスタンス変数へのアクセスを制限していないのですか?同期された宣言されたメソッドまたはsynchronized文のコードのみに制限されていますか?

public class stuff { 

    private int a = 10; 

    public synchronized void sync() { 
     long t1 = System.currentTimeMillis(); 
     System.out 
       .println("Okay, I am in sync method. I will be waiting for 10 seconds. Current Time = " 
         + System.currentTimeMillis()); 
     while (System.currentTimeMillis() - t1 < 10000); 
     System.out 
       .println("Okay, I have waited for 10 seconds. Current time is " 
         + System.currentTimeMillis() 
         + ".Now I will exit from sync method, a= " + this.a); 
    } 

    public void unsync() { 
     System.out 
       .println("Alright, I am in unsync method the currrent time is " 
         + System.currentTimeMillis()); 
     this.a = this.a + 1; 
     System.out.println("The time of exit from unsync method is " 
       + System.currentTimeMillis()); 

    } 
} 

class t1 extends Thread { 
    stuff s; 

    public t1(stuff s) { 
     this.s = s; 
    } 

    public void run() { 
     s.sync(); 
    } 
} 

class t2 extends Thread { 
    stuff s; 

    public t2(stuff s) { 
     this.s = s; 
    } 

    public void run() { 
     s.unsync(); 
    } 
} 

class m { 
    public static void main(String args[]) throws Exception { 
     stuff s = new stuff(); 
     t1 y = new t1(s); 
     t2 r = new t2(s); 
     y.start(); 
     Thread.sleep(2000); 
     r.start(); 
    } 
} 

プログラムの出力は以下の通りです:

 
Okay, I am in sync method. I will be waiting for 10 seconds. Current Time = 1358801766310 
Alright, I am in unsync method the currrent time is 1358801768343 
The time of exit from unsync method is 1358801768343 
Okay, I have waited for 10 seconds. Current time is 1358801776310.Now I will exit from sync method, 
a= 11 

答えて

16

はい。オブジェクトのモニターを保持すると、別のスレッドが別のコードブロックを実行したり、同じオブジェクトで同期したりすることがなくなります。メソッドが同期されていない場合は、別のスレッドがモニターを保持しているかどうかに関わらず、いつでも呼び出すことができます。

少なくとも1つのスレッドがこの共有状態を変更する可能性がある場合は、読み取り専用アクセスであっても共有にアクセスするたびに同期する必要があります。 、

まずそれがインターリーブする同じオブジェクトの同期メソッドの2つの呼び出しのために可能ではない:同期

3

これは、Javaでのモニターがインスタンス変数とのみ同期で同期宣言またはコードされているメソッドへのアクセスを制限していないということです声明?

はい。

同期化されたブロック(またはメソッド)は、とりわけ相互に排他的です。これはロックとして使用されるオブジェクト(モニタ、それをlockと呼ぶ)がこれらのブロックの外で使用されることを防ぎません。その場合、同期は実行されません。たとえば、あるスレッドがlockを読み書きすることができますが、別のスレッドはlockが同期しているブロック内にあります。

変数へのアクセスを制限する場合は、すべてのアクセスがロックを保持していることを確認する必要があります(アクセスごとに同じであれば任意のロック)。

2

作る方法は2つの効果があります。あるスレッドがオブジェクトの同期メソッドを実行しているとき、そのオブジェクトで最初のスレッドが完了するまで、同じオブジェクトブロックの同期メソッドを呼び出す他のすべてのスレッド(実行を中断)。

第2に、同期化されたメソッドが終了すると、同期化されたメソッドの後続の呼び出しと自動的に同じオブジェクトの同期化された関係が確立されます。これにより、オブジェクトの状態の変更がすべてのスレッドで認識できることが保証されます。

(出典:the Java tutorials

関連する問題