我最近看到了一个例子。我无法理解主线程和乘客线程如何一次保持在同步块中?
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
,并且根据定义,没有其他线程可以访问或输入任何同步的块或对象方法{{ 1}}!
答案 0 :(得分:4)
主线程和乘客线程如何一次保持在同步块中?
p.wait()
发布锁定p
,直到线程重新唤醒,因此synchronized
上任意数量的线程都可以p
为public final void wait() throws InterruptedException
只要最多一个人不等待。
notify
当前线程必须拥有此对象的监视器。 线程释放此监视器的所有权并等待,直到另一个线程通过调用
notifyAll
方法或{{1}}方法通知等待此对象监视器的线程唤醒。然后该线程等待,直到它可以重新获得监视器的所有权并继续执行。