0

ThreadAのコメント行に示されているように、ブロックのtimlesProc(100);内側または外側に配置する違いはありますか?synchronized

私の理解によると、両方のスレッドが実行モードにあり、両方を同時に実行できるため、違いはありません。しかし、実験によると、timlesProc(100);が内部にある場合synchronized、常に最初に実行され、次にb.sync.wait();「永遠に待機」する問題はありません。timlesProc(100);外にいるとき、synchronized私はいつも「ずっと待っている」と感じます。それはなぜですか、それとも私の理解は正しくありませんか?

class ThreadA {
public static void timlesProc(int count)
{
         for(int i=0;i<count;i++) 
           {
              System.out.println(Thread.currentThread().getName()+" "+ Integer.toString(i));
           }
}

    public static void main(String [] args) {
         ThreadB b = new ThreadB();

         b.start();

         //timlesProc(100);
         synchronized(b.sync) 
         {
            timlesProc(100);


            try 
            {
               System.out.println("Waiting for b to complete...");
               b.sync.wait();
               System.out.println("waiting done");

            } catch (InterruptedException e) {}



         }




     }
  }




class ThreadB extends Thread {   

     Integer sync = new Integer(1);
     public void run() {


        synchronized(sync) 
        {
           sync.notify();
            System.out.println("notify done");

        }  


     }
  }
4

2 に答える 2

4

競合状態があります。timlesProcメソッドが の外部にあるsynchronized場合、コンテキスト スイッチが発生し、もう一方がロックの取得とスレッドへの通知を実行できる可能性が非常に高くなります(待機していなくても)。そして、あなたがたどり着いたときThreadmain

b.sync.wait();

何も残ってnotify()いないので、あなたは永遠に待ちます。

timlesProcの中にを入れるとsynchronized、 に到達してwait()通知を受け取ります。その後、プログラムは終了します。

プログラムが永久に待機する別の可能性については、Cruncher's answerを参照してください。

于 2013-09-26T14:41:08.453 に答える
2

実際には、timlesProc呼び出しが同期ブロック内にある場合でも、競合状態が発生する可能性は低くなります。

発生した場合b.start()、メインスレッドの前に同期ロックを取得すると、最初に通知され、Sotirios Delimanolis が彼の回答で言及したのと同じ問題が発生します。

于 2013-09-26T14:49:23.707 に答える