繁体   English   中英

同步块中的代码

[英]Code in synchronized block

放置timlesProc(100);有什么区别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");

        }  


     }
  }

您有比赛条件。 如果timlesProc方法超出了synchronized ,这是非常可能的 ,你将有一个上下文切换,另一个Thread就可以执行获取锁,并通知main线程(即使它不是在等待)。 那当你到

b.sync.wait();

您将永远等待,因为没有任何东西可以notify()

如果你把timlesProc内部synchronized ,你到达wait()然后得到通知。 然后程序结束。

有关程序永久等待的另一种可能性,请参阅Cruncher的答案

实际上,即使timlesProc调用位于同步块内,也仍然存在竞争状态,发生的可能性较小。

如果b.start()发生了,并且它在主线程之前获取了同步锁,那么它将仍然首先通知,从而引起Sotirios Delimanolis在其答案中提到的相同问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM