2017-04-02 5 views
0

私は今、Javaの並行性を学んでいます。私はこのようなコードの一部に出くわした:このコードは、同期メソッドを呼び出すためにさまざまなオブジェクトを使用しているので同期されたメソッドが別のオブジェクトでロックされるのはなぜですか?

package pac1; 

import java.util.*; 
import java.util.concurrent.*; 

class A1 { 
    public void f() { 
     synchronized (this) { 
      for (int i = 0; i < 5; i++) 
       System.out.println("f()"); 
     } 
    } 
} 

class B1 { 
    public void g() { 
     synchronized (this) { 
      for (int i = 0; i < 5; i++) 
       System.out.println("g()"); 
     } 
    } 
} 

class C1 { 
    public void p() { 
     synchronized (this) { 
      for (int i = 0; i < 5; i++) 
       System.out.println("p()"); 
     } 
    } 

} 

public class V { 
    public static void main(String[] args) { 
     A1 a = new A1(); 
     B1 b = new B1(); 
     C1 c = new C1(); 
     new Thread() { 
      public void run() { 
       a.f(); 
      } 
     }.start(); 
     new Thread() { 
      public void run() { 
       c.p(); 
      } 
     }.start(); 
     b.g(); 
    } 

} 

、私はそれが相互に干渉することを防ぐないだろうと推測しました。しかし、結果は次のとおりです。BTW

​​

、結果は同じ使用してロックである:実際に

package pac1; 

import java.util.*; 
import java.util.concurrent.*; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; 

class A { 
    Lock lock = new ReentrantLock(); 

    public void f() { 
     lock.lock(); 
     try { 
      for (int i = 0; i < 5; i++) 
       System.out.println("f()"); 
     } finally { 
      lock.unlock(); 
     } 
    } 
} 

class B { 
    Lock lock = new ReentrantLock(); 

    public void g() { 
     lock.lock(); 
     try { 
      for (int i = 0; i < 5; i++) 
       System.out.println("g()"); 
     } finally { 
      lock.unlock(); 
     } 
    } 
} 

class C { 
    Lock lock = new ReentrantLock(); 

    public void p() { 
     lock.lock(); 
     try { 
      for (int i = 0; i < 5; i++) 
       System.out.println("p()"); 
     } finally { 
      lock.unlock(); 
     } 
    } 
} 

public class Ex16 { 

    public static void main(String[] args) { 
     A a = new A(); 
     B b = new B(); 
     C c = new C(); 
     new Thread() { 
      public void run() { 
       a.f(); 
      } 
     }.start(); 
     new Thread() { 
      public void run() { 
       c.p(); 
      } 
     }.start(); 
     b.g(); 
    } 

} 
+0

さらに多くのものを印刷してみてください。最初のスレッドのメソッドを実行している間にJavaが終了し、2番目のスレッドのメソッドを実行してから、実際にメインメソッドの実行が終了する前に、すべてが1,3,2の順序で印刷されます。私はあなたがそれぞれ1000人いたら混乱するだろうと思う。 – gandaliter

+0

彼らはお互いに干渉していると思いますか?各繰り返しでThread.sleep(500)への呼び出しを追加します。 –

答えて

0

ループは単純に十分な長さ、したがってスレッドが同じ順序で確定することができますされていない彼らが発足した。スレッドが干渉しないことを明らかにするには、以下のいずれかの方法を試してみてください。

  • ループを長く実行します。 1000回の反復が十分に、より多くのようになります。

    synchronized (this) { for (int i = 0; i < 1000; i++) System.out.println("f()"); }

  • は、ループ内のスレッドを中断したが、各ループに設定された異なる間隔を持っていることを確認してください。

    synchronized (this) { for (int i = 0; i < 5; i++) { System.out.println("p()"); try { Thread.sleep(3000); } catch (final InterruptedException ex) { // Swallow } } }

限りストーリーショート:これらのロックは実際には干渉しません。

1

ここではロックや同期は必要ありません。 Sychronizedは、共有可能な可変状態へのアクセスをロックするために使用されます。まず、共有可能な可変状態はありません。

ここに3つのスレッドがあり、誰もコンテキスト切り替えのためにスレッドが実行される順序を予測できません。私は問題を見ません。

関連する問題