2016-10-03 5 views
0

Javaのスレッド同期を勉強しようとしていましたが、同期ブロックについて知りました。私はスレッドの同期についてはあまり知らないので、愚かな質問をしているかもしれませんが、このプログラムではブロックの動作を理解していません。Javaの同期ブロックを理解できません

class Table { 
    void printTable(int n) { //method not synchronized 
     for(int i=1; i<=10; i++) { 
      System.out.println(n + " * " + i + " = " + n*i); 
      try { 
       Thread.sleep(500); 
      } catch(Exception e) { 
       System.out.println(e); 
      } 
     } 
     System.out.println("Table of " + n + " is completed."); 
    } 
} 

class MyThread extends Thread { 
    Table t; 
    int num; 

    MyThread(Table t, int num) { 
     this.t = t; 
     this.num = num; 
    } 

    public void run() { 
     synchronized(t) { 
     t.printTable(num); 
     } 
    } 
} 

class TestSynchronization { 
    public static void main(String[] args) { 
     Table obj = new Table(); //only one object 
     MyThread t1; 
     MyThread t2; 

     t1 = new MyThread(obj, 10); 
     t2 = new MyThread(obj, 17); 

     t1.start(); 
     t2.start(); 
    } 
} 

それは出力です。このようなものです:

適切なようだが、私はrunメソッドから同期ブロックを削除し、 void mainobjオブジェクトにそれをappyingことにより、同じことをしようとすると、それは違う示し
10 * 1 = 10 
10 * 2 = 20 
10 * 3 = 30 
10 * 4 = 40 
10 * 5 = 50 
Table of 10 is completed. 
17 * 1 = 17 
17 * 2 = 34 
17 * 3 = 51 
17 * 4 = 68 
17 * 5 = 85 
Table of 17 is completed. 

出力。

class Table { 
    void printTable(int n) { //method not synchronized 
     for(int i=1; i<=5; i++) { 
      System.out.println(n + " * " + i + " = " + n*i); 
      try { 
       Thread.sleep(500); 
      } catch(Exception e) { 
       System.out.println(e); 
      } 
     } 
     System.out.println("Table of " + n + " is completed."); 
    } 
} 

class MyThread extends Thread { 
    Table t; 
    int num; 

    MyThread(Table t, int num) { 
     this.t = t; 
     this.num = num; 
    } 

    public void run() { 
     t.printTable(num); 
    } 
} 

class TestSynchronization { 
    public static void main(String[] args) { 
     Table obj = new Table(); //only one object 
     MyThread t1; 
     MyThread t2; 

     synchronized(obj) { 
     t1 = new MyThread(obj, 10); 
     t2 = new MyThread(obj, 17); 
     } 

     t1.start(); 
     t2.start(); 
    } 
} 

出力:

10 * 1 = 10 
17 * 1 = 17 
10 * 2 = 20 
17 * 2 = 34 
17 * 3 = 51 
10 * 3 = 30 
17 * 4 = 68 
10 * 4 = 40 
10 * 5 = 50 
17 * 5 = 85 
Table of 17 is completed. 
Table of 10 is completed. 

これは2番目の場合には動作しないのはなぜ私に説明してください。

可能であれば、void mainで同期ブロックを使用して同じ出力を得る方法をお勧めします。

+0

なぜ落札したらいいですか?あなたがこれが宿題の問題だと思っているのでなければ、質問は私には完全に合理的だと思われます。... hmmm – ultrajohn

答えて

1

差は、テーブルクラスのオブジェクトにlockを取得したとあります。

最初の例では、MyThreadクラスのインスタンス内でテーブルオブジェクトへのロックが取得されました。 MyThreadクラスの最初のインスタンスがテーブルオブジェクトのロックを取得したとすると、他のインスタンスのMyThreadクラスは、最初のオブジェクトを解放するまでテーブルオブジェクトへのロックを取得できません。スレッドレベルの同期

2番目の例では、ドライバプログラムによってオブジェクトへのロックが取得されたため、技術的にはロックはドライバプログラムに関連付けられているため、このレベルでは並行性の問題は発生しません。実際には種類プロセスレベルの同期です。

+0

ありがとう@ultrajohn。今私は間違いがある。概念も理解されています。実際、私はJava同期の初心者なので、このコンセプトを得ることはできませんでした。 –

+1

@Niraj、No prob。私の好意を持ち、私のポストに投票してください。 :)ありがとう。 – ultrajohn

+0

確かに。 @ultrajohn –

0

同期化されたブロックはルームであり、同期化されたブロックはオブジェクトに適用されます。 最初の例では、同期ブロックがクラステーブルオブジェクトに適用されます。 スレッドにメソッドにアクセスしようとすると、まず人が部屋に入るように同期ブロックに入る必要があります。また、t1のようなスレッドがブロックに入ると、実行はt1で終了するまでロックされます。 t2は部屋に入ることができます。

t1がt2の直前に実行を終了すると出力が異なることがありますが、大きなアプリケーションの場合は干渉して異なる出力2番目の例で説明したように配置します。我々はsynchronizedブロックを使用するか、

0

は、相互に排他的なブロック

synchronized(mutex){ 
    x =y; 
    y=z; 
    } 

ミューテックスを=同期などのブロッキングキュー、などの安全なクラスをthrceadなinterleivingを防ぐためにそう 。 同じオブジェクトを共有するスレッドの一覧から1つのスレッドで実行できるブロックつまりmutex

最初にmutexはオブジェクトで、javaの各オブジェクトにはlockというセモフォアがあります。スレッドAと、ブロックを同期させるために入る前にスレッド CとBがミューテックスを共有しているが、ロック を取得する必要があります

場合すなわち取得は入り口

前に発生し、一つのスレッドがすでに取得した場合の前に、すなわちを取得起こるリリースロックは、最初のスレッドがロックを解放しなくなるまで待たなければなりません。

同期ブロックの別の機能は、ロックを獲得した各スレッドが、ブロックに含まれるすべての変数をキャッシュから直接読み込む必要があり、変更された場合はそれらをメインメモリに書き込む必要がありますブロック。

つまり、取得後に変数値の更新が発生し、リリース前にメモリ書き込みが行われるため、次のスレッドは処理する最新の値を持ちます。

関連する問題