2016-12-18 11 views
1

マルチスレッドに関して、同じオブジェクトに2つのスレッド(スレッド1とスレッド2)があるとします。スレッド1は同期されたmethod1()にあり、スレッド2はjavaで同時にsynchronized method2()を何らかの方法で入力できます。2つのスレッドがインスタンスレベルのロックで同時に2つの異なる同期メソッドに入る

私はここでスレッド1が同期されたmethod1()にロックされている必要があり、同期されたmethod1()を終了したときにのみ、オブジェクトのモニタでロックを解除する必要があります。したがって、Thread-2はThread-1がオブジェクトのモニター上でロックを解放して同期されたmethod2()に入るのを待たなければなりません。どのような方法によって、Javaで同時に

それでもアドバイスしてください、(同期方法2を入力するスレッド2によってどのような方法がある)は、任意のハックがあり、このことを達成するために場合は、以下の

は私のプログラム、儀式であります今私は、以下のプログラムの出力は以下の

inside M1() 
t1--->RUNNABLE 
inside M2() 
t2--->RUNNABLE 

あるようになりました。この上でアドバイスしてくださいすることは、私の更新されたコード

public class Test { 

    private final Object lockA = new Object(); 
    private final Object lockB = new Object(); 

    public void m1() { 
     synchronized(lockA) { 
     try { 
      System.out.println("inside M1()"); 
      Thread.sleep(100);   
     } 
     catch (InterruptedException ie) 
     {} 
     } 
    } 

    public void m2() { 
     synchronized(lockB) { 
     try { 
      System.out.println("inside M2()"); 
      Thread.sleep(100); } 
     catch (InterruptedException ie) {} 
    } 
    } 

    public static void main(String[] args) throws InterruptedException { 
     final Test t = new Test(); 
     Thread t1 = new Thread() 
     { public void run() { t.m1(); } }; 
     Thread t2 = new Thread() 
     { public void run() { t.m2(); } }; 

     t1.start(); 
     //Thread.sleep(500); 

     t2.start(); 
     // Thread.sleep(500); 

     System.out.println("t1--->"+t1.getState()); 
     System.out.println("t2--->"+t2.getState()); 
    } 
} 
+1

[2つの同期メソッドを同時に実行する](0120-919-03) –

+1

両方のスレッドが取得済みであるという証拠はまだありません同じロックを同時に使用することができます。あなたが示唆していることは、基本的に想像がつかないことです。 – EJP

+0

@EJP、Thnaksしかし、どのロックが取得されているかを簡単に証明できる方法を教えてください。ロック名を見る方法はありますか? –

答えて

1

お知らせ股関節での実装を変更しましたMyRunnable1クラスに1つのmethod1()があり、run()関数がループ内でこのメソッドを呼び出していても、サンプルスレッドのtはどんな場合でも競合しません。なぜなら、thread1とthread2は異なるインスタンスであり、それぞれにはmethod1()という独自のコピーがあるため、synchronizedによって使用されるロックは異なるものであり、単一のロックではありません。

+0

同じロックを使用する単一の実行可能ファイルを使用しているため、私はあなたに同意しません。メソッドは共有され、他のコピーはありません。 – Tony

+0

あなたは正しいです私は間違いを私の間違いに気付かなかった – urag

0

2つのスレッドが同じロックを同時に保持することはできません。しかし、スレッドがオブジェクトのメソッドである​​の中にあるという理由だけで、スレッドはロックを保持しているというわけではありません。たとえば、条件変数にawaitを呼び出し、待機中にロックを解放することができます。これにより、他のスレッドが​​メソッドを入力することでロックを取得できるようになります。結局のところ、それはあなたが待っているものです。

+0

このスレッドで唯一の正しい答えと唯一の1つの投票で... – Voo

0

あなたのコードは次のようなものです:

void method1(){ 
     synchronized(this) { 
      //... 
     } 
} 

synchronized void method2(){ 
     synchronized(this) { 
      //... 
     } 
} 

そして、あなたのコードでは、2つのスレッドがロック競合のため、同時に2つの方法を入力することはできません。実行可能なインスタンスの異なるインスタンス、つまりこれと異なるインスタンスでのみ実行できます。

+0

これは正しくありません。私の答えを参照してください - それらの '// ... 'の中には、ロックを解除するコードが含まれていて、別のスレッドが' synchronized'ブロックを入力できるようにすることができます。 –

+0

@DavidSchwartz私は彼の古いコードサンプルでは、​​別のインスタンスを使用する以外は実行できません。 :) – Tony

0

すべてのオブジェクトにロックが関連付けられていて、Thread1がsynchronizedメソッド1にアクセスするためにロックを取得すると、Thread2はsynchronizedメソッド2にアクセスできません。

今、特別な場合に来て、あなたはいつでも簡単なハックを行うことができます。スレッド1がロックを持っていて、同期メソッド1にアクセスしているとします。メソッド1の中で、Thread1が変数のwaitを呼び出すと、オブジェクトのロックが解除され、待機状態になります。このシナリオでは、スレッド2はロックを取得し、同期メソッド2を入力できます。したがって、両方のスレッドは同じobj上の異なる同期メソッドにアクセスできます。

P.S.これは単なる例ですが、同期ブロック内に別の待ち時間を持たせることはお勧めできません。不必要な複雑化につながります。これを行うコードがあれば、ロジックとデザインに欠陥があることを意味します。

関連する問題