2017-11-16 6 views
1

コード:二つの質問(通知使用)方法

public class NotifyAndWaitTest2 implements Runnable { 
    public int i = 0; 
    public Object lock; 
    public SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); 

    public NotifyAndWaitTest2(Object o) { 
     this.lock = o; 
    } 

    @Override 
    public void run() { 
     synchronized (lock) { 
      System.out.println(Thread.currentThread().getName() + " enter the SYNCHRONIZED block --- "+ sdf.format(new Date())); 
      try { 
       while (i < 9) { 
        Thread.sleep(500); 
        lock.notify(); 
        lock.wait(); 
        System.out.println(Thread.currentThread().getName() + " say:" + i++ + " --- " + sdf.format(new Date())); 
       } 
       lock.notify(); 
       return; 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     Object lock = new Object(); 
     NotifyAndWaitTest2 test = new NotifyAndWaitTest2(lock); 
     Thread t1 = new Thread(test,"Thread A"); 
     Thread t2 = new Thread(test,"Thread B"); 
     Thread t3 = new Thread(test,"Thread C"); 
     Thread t4 = new Thread(test,"Thread D"); 
     t1.start(); 
     t2.start(); 
     t3.start(); 
     t4.start(); 
    } 
} 

結果:

Thread A enter the SYNCHRONIZED block --- 10:47:07.242 
Thread B enter the SYNCHRONIZED block --- 10:47:07.743 
Thread C enter the SYNCHRONIZED block --- 10:47:08.243 
Thread D enter the SYNCHRONIZED block --- 10:47:08.743 
Thread C say:0 --- 10:47:09.243 
Thread D say:1 --- 10:47:09.744 
Thread C say:2 --- 10:47:10.244 
Thread D say:3 --- 10:47:10.744 
Thread C say:4 --- 10:47:11.245 
Thread D say:5 --- 10:47:11.745 
Thread C say:6 --- 10:47:12.246 
Thread D say:7 --- 10:47:12.746 
Thread C say:8 --- 10:47:13.247 
Thread D say:9 --- 10:47:13.247 
Thread B say:10 --- 10:47:13.247 
Thread A say:11 --- 10:47:13.247 

コードは両方jdk1.7に同じ結果を実行しjdk1.8。

私の問題:スレッドのCとスレッドDは、スレッドAの代わりに入力している理由は、スレッドAとスレッドBの後

  • が同期ブロックを入力し、(待機を呼び出す)方法は、iと、スレッド言いますBは言う?シンクブロックの入力優先度は、wait()メソッドを呼び出したスレッドよりも高いですか?なぜ待つだけ()メソッドを呼び出した最新のスレッドを覚ます?通知()メソッドと呼ばれる

  • スレッドCとスレッドDのように、お互いに通知し、お互いに待って、なぜ他の待ちスレッドではないのですか?スレッドAとスレッドBの

ように私は

Thread A enter the SYNCHRONIZED block 
Thread B enter the SYNCHRONIZED block 
Thread A say:0 
Thread C enter the SYNCHRONIZED block 
Thread B say:1 
Thread A say:2 
Thread D enter the SYNCHRONIZED block 
Thread B say:3 
Thread C say:4 
+0

予想される結果は何ですか? –

+0

@EvgeniyDorofeev質問を再編集しました – PriestM

答えて

1

のように、それはランダムであるべきだと思う質問1:

スレッドAとスレッドBは、同期ブロックを入力した後と 待ち()メソッドを呼び出して、なぜスレッドCとDのスレッドは、スレッド Aの代わりに入っているiと、スレッドBは、私が言うの?と言いますかただ待ち()メソッド呼び出したスレッドよりも高いブロック 同期に入るの優先順位は?ここで

Javadoc約待ち時間は/通知こう言われる、

現在 のスレッドがこのオブジェクトのロックを解除するまで再開されたスレッドが続行することはできません。 目覚めスレッドが 積極的にこのオブジェクトを同期させるために、競合する可能性のある他のスレッドと通常の方法で競争します。例えば、 目覚めのスレッドがこのオブジェクトをロックする 次のスレッドであることには信頼性の高い特権または不利益を楽しんでいません。

これが意味することは、そのスレッドAは、スレッドBがnotifyを呼び出したときに進み、Aは同期ブロックの開始時に待機しているスレッドのCとDと競争する必要がありますスレッドに保証されませんです。実装では、スレッドCとDを優先します。あなたは、この出力を参照してください理由です:

Thread A enter the SYNCHRONIZED block --- 10:47:07.242 
Thread B enter the SYNCHRONIZED block --- 10:47:07.743 
Thread C enter the SYNCHRONIZED block --- 10:47:08.243 
Thread D enter the SYNCHRONIZED block --- 10:47:08.743 

質問2:

理由だけ 待ち()メソッドを呼び出した最新のスレッドを覚ます通知()メソッドと呼ばれますか?スレッドCとスレッドDのように、お互いに を通知し、お互いに待っています。同様のスレッド AとスレッドB

ここでもJava仕様は優先順位を保証しません。スレッドDからnotifyを呼び出すと、スレッドC(スレッドAとBと共にロックを待機しています)が起動し、スレッドCが "say"ステートメントを出力してから500msの間スリープしてスレッドCを呼び出します再度、スレッドAとB)と一緒に、ロックを待機しているまで、彼らの出口ながら、私の実験からのループと同期ブロックので、Bをスレッドに最初のロックを解除してからスレッドするA.

出力例:

Thread A enter the SYNCHRONIZED block --- 09:35:59.836 
Thread D enter the SYNCHRONIZED block --- 09:36:00.336 
Thread C enter the SYNCHRONIZED block --- 09:36:00.836 
Thread B enter the SYNCHRONIZED block --- 09:36:01.336 
Thread C say:0 --- 09:36:01.836 
Thread B say:1 --- 09:36:02.337 
Thread C say:2 --- 09:36:02.837 
Thread B say:3 --- 09:36:03.337 
Thread C say:4 --- 09:36:03.837 
Thread B say:5 --- 09:36:04.337 
Thread C say:6 --- 09:36:04.837 
Thread B say:7 --- 09:36:05.337 
Thread C say:8 --- 09:36:05.837 
Thread B say:9 --- 09:36:05.837 
Thread D say:10 --- 09:36:05.837 
Thread A say:11 --- 09:36:05.838 
+0

あなたの答えがありがとう、私はスレッドが競争する必要があることを理解しています、あなたはこの質問の説明で思うランダムな状況が表示されると思いますか?私はこのコードを何度もテストし、常に4つのスレッドをsyncブロックに入れ、最後の2つのスレッドがお互いに繰り返し起きて "say"を出力します。なぜこれがいつものような状況ではないのは分かりません。 – PriestM

+0

ランダムでも、同じ出力を何回も繰り返すこともできます。それはすべてJavaのバージョンとそれが動作しているオペレーティングシステムに依存します。それがどのように私のために印刷されたかについての更新された答えを見てください。 – tsolakp

+0

ありがとう、私はまだこの問題についていくつかの疑問を持って、私は学び続け、この理由を理解しようとする – PriestM

関連する問題