【发布时间】:2021-03-30 18:46:38
【问题描述】:
我怀疑在 java 线程同步中让我有些困惑,如果我有一个共享内存区域,那么在同步方法中使用 wait/notify/notifyAll 和声明一个 Object (Object myObj) 和使用有什么区别myObj.wait,据我了解,两者都达到了相同的效果。
换句话说: 这个
public class ThreadSignal{
protected boolean isDataAvailable = false;
public void synchronized waitUntilComplete(){
if(isDataAvailable == false){
wait();
}
}
public void synchronized complete(){
isDataAvailable = true;
notify();
}
}
vs这个
private Object notEmpty = new Object();
private Object notFull = new Object();
public synchronized E take() {
//some code
notEmpty.wait()
//some code
notFull.notifyAll();
}
区别在于第一个锁定整个对象,因此没有其他线程可以访问该共享区域,而在第二个中,我们可以更灵活地锁定我们想要锁定的对象吗?
第二个问题,因为将其放在评论中很难(为其编辑主要帖子):
我有一个问题我试图解决并找出构建课程的最佳方法,问题如下有一个带有队列(共享区域)和三个线程(飞行员、女主人和乘客)的机场,女主人是基本上是从机场办理登机手续。
乘客首先进入队列等待女主人的操作checkDocuments(因此进入阻塞/等待状态)然后出示机票并等待女主人的操作waitForNextPassenger进入机内。另一方面,女主人被乘客的 waitInQueue 操作唤醒(当它第一次进入队列时),检查乘客,然后进入另一个等待状态,等待乘客文件,然后检查乘客。
鉴于此,我定义了这些阻塞变量: 等待队列 检查文件 展示文件 等待下一个乘客
鉴于您在评论中所说的,我想一个好的方法是将这些中的每一个都设为一个对象,例如在线程乘客生命周期中,它会调用等待对象 checkDocuments (checkDocuments.wait) 的方法 WaitInQueue ) 并且女主人会例如 checkDocuments.notify
这是一个正确的方法吗?
【问题讨论】:
-
嗯,它们只是不同而已。一个区别是第一个锁定整个对象,因此锁定是外部的,并且对任何引用该对象的人都是可见的。但锁定策略似乎也不同(两个锁对一个),
notify()和notifyAll()做不同的事情。 -
好吧,我放置的示例不同,但我可以通过技术上执行 Object isDataAvailable; 来完成第一个示例;然后不是等待,而是执行 isDataAvailable.wait,然后执行 isDataAvailable.notify。主要区别是什么
标签: java multithreading synchronization