java中的ReentrantLock条件等待获取IllegalMonitorStateException

java中的ReentrantLock条件等待获取IllegalMonitorStateException,java,multithreading,Java,Multithreading,我的应用程序将继续监视一个文件夹,一旦它不是空的,它将唤醒工作线程。将在等待过程中引发IllegalMonitorStateException 原因是什么 import java.io.File; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import org.apache.commons.io.FileUtils; public class Loc

我的应用程序将继续监视一个文件夹,一旦它不是空的,它将唤醒工作线程。将在等待过程中引发IllegalMonitorStateException

原因是什么

import java.io.File;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.io.FileUtils;

public class LockTest {

    public static void main(String[] args) {
        String folder = "C:\\temp\\test";

        final ReentrantLock messageArrivedLock = new ReentrantLock();
        final Condition messageArrivedCondition = messageArrivedLock.newCondition();

        Thread workerThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("worker thread is running");
                messageArrivedLock.lock();
                while (true) {
                    System.out.println("worker thread is waiting");
                    try {
                        messageArrivedCondition.wait(); //Exception here 
                        System.out.println("worker thread wakes up");
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        if (messageArrivedLock.isHeldByCurrentThread()) {
                            messageArrivedLock.unlock();
                        }

                    }
                }
            }
        });

        workerThread.start();

        while (true) {
            long size = FileUtils.sizeOf(new File(folder));
            System.out.println("size:" + size); // 1000

            messageArrivedLock.lock();

            try {
                if (size > 0) {
                    messageArrivedCondition.signalAll();
                }
            } finally {
                if (messageArrivedLock.isHeldByCurrentThread()) {
                    messageArrivedLock.unlock();
                }

            }

        }

    }

}

我将假设您打算调用,这通常(就像这里的情况一样)具有与
Object#wait
相同的行为

假设当前线程持有与此关联的锁 调用此方法时的条件。这取决于执行情况 确定情况是否如此,如果不是,如何应对。 通常会引发异常(例如
IllegalMonitorStateException
),实现必须记录 这是事实

大概您的
循环迭代了一次,最后释放了
中的锁。在第二次迭代中,线程没有锁,因此调用
wait
将抛出
IllegalMonitorStateException
。线程需要拥有锁才能在相关的
条件下调用
wait


您可以在
while
循环中获取锁。

我做到了,在第一个while循环中获取锁,仍然是相同的错误。@Jean FrançoisSavard为了让线程从
wait
调用返回,线程需要重新获取锁,因此,当在
finally
块中调用
unlock
时,锁将由线程拥有。@user595234是的,但是您是否将
对象#wait
更改为
条件#wait
?为什么不能使用对象#wait?@ed22这不是这里使用的模式。
锁定
对象与
条件
信号
等待
一起工作。要使用
wait
,您需要使用
synchronized
notify