ReentrantLock条件等待在java中获取IllegalMonitorStateException

时间:2015-03-30 16:37:15

标签: 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 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();
                }

            }

        }

    }

}

1 个答案:

答案 0 :(得分:2)

我将假设你打算调用Condition#await,这通常会(就像这里的情况一样)与Object#wait遇到的行为相同。

  

假设当前线程持有与此关联的锁   调用此方法时Condition。这取决于实施   确定是否是这种情况,如果不是,如何回应。   通常,会抛出异常(例如   IllegalMonitorStateException)并且实施必须记录   那个事实。

大概你的while循环迭代了一次,释放了finally内的锁。在第二次迭代中,您的线程没有锁,因此调用wait将抛出IllegalMonitorStateException。您的线程需要拥有锁才能在关联的await上调用Condition

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