Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-对对象调用wait(),然后允许对象访问方法_Java_Multithreading_Concurrency_Wait - Fatal编程技术网

Java-对对象调用wait(),然后允许对象访问方法

Java-对对象调用wait(),然后允许对象访问方法,java,multithreading,concurrency,wait,Java,Multithreading,Concurrency,Wait,我有一个以线程作为参数的方法。我希望这个方法能够使一个线程等待,如果没有一个线程已经在等待,然后当另一个线程进入该方法时唤醒,以便它们两个可以交互。我想我很接近了,但是在我对第一个线程调用wait()之后,没有其他线程可以访问该方法。以下是我的代码的最低版本: // In the class 'Node' public synchronized void trade(Thread thread) { if (!threadWaiting) { threadWait

我有一个以线程作为参数的方法。我希望这个方法能够使一个线程等待,如果没有一个线程已经在等待,然后当另一个线程进入该方法时唤醒,以便它们两个可以交互。我想我很接近了,但是在我对第一个线程调用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将调用节点的trade()方法并将自身传递给该方法。如果Bot是方法中的第一个,那么我希望它的线程在节点上等待,直到另一个Bot出现(等待的Bot将存储在节点中),此时两个Bot将交互。 下面是我的伪代码方法的一个更清晰的示例:

// 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;
    }
}

很抱歉我原来的帖子的措辞

您的实现有一个缺陷。您正在锁定传递的参数,这对于所有线程都是不同的,因此它们不能与wait notify交互

编辑:我不确定你的目标到底是什么,但基于细节,这可能会有所帮助: EDIT2:添加了锁()

编辑:
查看更新后的帖子,您应该使用cyclicbarrier和count 2,然后这应该可以为您解决所有问题。

这与loki的代码类似,但有所改进

private final Lock lock = new ReentrantLock();
private final Condition cnd = lock.newCondition();
private final AtomicBoolean threadwaiting = new AtomicBoolean(false);

public void trade(Thread thread) {
    lock.lock();

    if (threadwaiting.get()) {
        cnd.signalAll();
        lock.unlock();
        // perform your task of second thread
    } else {
        threadwaiting.set(true);
        try {
            cnd.await();
            // perform your task of first thread
        } catch (InterruptedException e) {
        } finally {
            threadwaiting.set(false);
            lock.unlock();
        }
    }
}

这是一个死锁,因为当您调用
thread.wait()时释放线程对象锁。但是
这个
同步方法上的对象锁定仍然存在,这就是为什么没有其他人可以进入它。

您希望他们如何交互?如果你想将数据从一个线程传递到另一个线程,你可以使用一个“你有没有研究过”或“类?”的方法,但这不起作用,我仍然得到相同的结果。我用更多的信息更新了我的答案,因为我可能没有很好地解释我自己。
private final Lock lock = new ReentrantLock();
private final Condition cnd = lock.newCondition();
private final AtomicBoolean threadwaiting = new AtomicBoolean(false);

public void trade(Thread thread) {
    lock.lock();

    if (threadwaiting.get()) {
        cnd.signalAll();
        lock.unlock();
        // perform your task of second thread
    } else {
        threadwaiting.set(true);
        try {
            cnd.await();
            // perform your task of first thread
        } catch (InterruptedException e) {
        } finally {
            threadwaiting.set(false);
            lock.unlock();
        }
    }
}