1

我最近在下面看到了一个例子。我无法理解主线程和乘客线程如何同时保持在同步块中?

public class bus 
{
    public static void main(String[] args) throws InterruptedException 
    {
        passenger p = new passenger();
        p.start();
        synchronized (p) 
        {
            System.out.println("passenger is waiting for the bus, i am in synchronised method");
            p.wait();
            System.out.println("passenger  got notification");
        }
        System.out.println("after "+p.total+" time");
    }
}

class passenger  extends Thread 
{
    int total = 0;

    public void run() 
    {
        synchronized (this) 
        { 
            System.out.println("wait ....  i am in synchronised method");
            for (int i = 0; i <= 1000; i++)
            total = total + i;
            System.out.println("passenger  is given  notification call");
            notify();
        }
    }
} 

这个程序的输出是

passenger is waiting for the bus i am in synchronised method
wait ....  i am in synchronised method
passenger  is given  notification call
passenger  got notification
after 500500 time

这意味着当主线程打印“乘客正在等待我在同步方法中的公共汽车”时,它已经处于同步块并等待。打印的下一条语句是“等待......我在同步方法中”,这意味着乘客线程也进入了它的同步块。请记住,两个同步块具有相同的对象 -p作为块对象。这似乎令人困惑,因为我知道当主线程进入synchronized(p)块时,主线程必须阻塞对象p,并且根据定义,没有其他线程可以访问或进入对象的任何同步块或方法p

4

1 回答 1

4

主线程和乘客线程如何同时保持在同步块中?

p.wait() 释放锁定p直到线程重新唤醒,因此只要最多有一个不等待,任意数量的线程都可以synchronized打开。p

来自Object的 javadoc

public final void wait() throws InterruptedException

当前线程必须拥有该对象的监视器。线程释放此监视器的所有权notify并等待,直到另一个线程通过调用方法或方法通知在此对象的监视器上等待的线程唤醒notifyAll。然后线程等待直到它可以重新获得监视器的所有权并恢复执行。

于 2013-04-26T19:57:46.747 回答