我有一个将线程作为参数的方法。我希望这个方法能够让一个线程在没有线程等待的情况下等待,然后在另一个线程进入该方法时唤醒,以便它们两个可以交互。我想我已经接近了,但是在我在第一个线程上调用 wait() 之后,没有其他线程可以访问该方法。这是我的代码的极简版本:
// In the class 'Node'
public synchronized void trade(Thread thread)
{
if (!threadWaiting)
{
threadWaiting = true;
synchronized(thread)
{
try {
thread.wait();
} catch (InterruptedException e) {...}
}
}
}
我很抱歉遗漏了任何明显的东西,我一直在四处寻找答案,但我是线程的新手,所以我不知道要寻找什么。
所以我的问题是,当另一个线程试图进入 trade() 时,他们不能,调试器就停在那里。
编辑: 这是我要问的更多说明。恐怕我在原来的帖子中并不太清楚。
所以我有一个名为 Node 的类和另一个名为 Bot 的类。 Bot 扩展线程以便它可以暂停。在程序开始时,创建并启动多个 Bot 对象,然后每个 Bot 将调用 Node 的 trade() 方法并将自身传递给该方法。如果一个机器人是方法中的第一个,那么我希望它的线程在节点上等待,直到另一个机器人出现(等待的机器人将存储在节点中),此时两个机器人将进行交互。 下面是我的方法在伪代码中的一个更清晰的示例:
// Variable to hold the bot that is waiting.
private Bot waitingBot = null;
// Method belonging to Node.
public synchronized void trade(Bot currentBot)
{
if (waitingBot == null)
{
waitingBot = currentBot;
waitingBot.wait();
}
else
{
currentBot.interactWith(waitingBot);
waitingBot.notify();
waitingBot = null;
}
}
对我原来帖子的措辞感到抱歉。
最佳答案
您的实现存在缺陷。您正在锁定传递的参数,这对于所有线程都是不同的,因此它们无法与等待通知交互。
编辑:我不确定你的目标到底是什么,但根据细节,这可能会有所帮助: EDIT2:添加了 lock()
private final Lock lck = new ReentrantLock();
private final Condition cnd = lck.newCondition();
private final AtomicBoolean threadwaiting = new AtomicBoolean(false);
public synchronized void trade(Thread thread)
{
lck.lock();
try{
if(threadwaiting.get()){
cnd.signalAll();
threadwaiting.set(false);
//perform your task
}else{
cnd.await();
threadwaiting.set(true);
}
}
} finally {
lck.unlock()
}
}
编辑: 查看您更新后的帖子,您应该将 cyclicbarrier 与 count 2 一起使用,这样应该可以为您解决所有问题。
关于Java - 在对象上调用 wait() 然后允许对象访问方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16120248/