同步块中的代码

时间:2013-09-26 14:35:32

标签: java multithreading

timlesProc(100);置于synchronized块内部或外部,如ThreadA中显示的注释行,是否有任何区别。

根据我的理解,没有区别,因为两个线程都处于运行模式,并且两者都可以在同一时间执行。但根据实验,当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");

        }  


     }
  }

2 个答案:

答案 0 :(得分:4)

你有竞争条件。如果timlesProc方法超出synchronized,则非常可能您将进行上下文切换,而另一个Thread将能够执行获取锁定并通知main线程(即使它没有等待)。然后当你到达

b.sync.wait();

你永远等待,因为notify()没有留下任何东西。

如果您将timlesProc放在synchronized内,则会转到wait(),然后会收到通知。然后程序结束。

请参阅Cruncher's answer了解程序永远等待的另一种可能性。

答案 1 :(得分:2)

实际上,即使timlesProc调用在同步块内,仍然存在竞争条件,不太可能发生。

如果b.start()发生,并且它在主线程之前获取同步锁定,那么它仍将首先通知导致Sotirios Delimanolis在其answer中提到的相同问题。