【发布时间】:2014-05-19 07:03:23
【问题描述】:
当线程处于被ReentrantLock 锁定的临界区时,我需要以某种方式停止线程 1 秒。
我的代码是:
public class Lock implements Runnable {
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + " is running !");
lock.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
Lock lock = new Lock();
Thread thread = new Thread(lock);
thread.start();
}
}
当我在 run() 方法中调用 lock.wait(1000) 时,它会抛出 IllegalMonitorStateException。
如果我通过lock.lock()方法获得了监控,为什么会出现这个异常?
当我调用super.wait(1000) 而不是lock.wait(1000) 时,也会发生同样的情况。
【问题讨论】:
-
这不是
lock.wait所做的。wait原子地释放lock并挂起线程。这是wait/notifyAPI 的一部分——它继承自Object,而不是Lock的一部分。为了调用wait,您必须拥有对象上的监视器——即您必须是synchronized。您正在寻找Thread.sleep。 -
为什么会出现
IllegalMonitorStateException? -
因为你处于非法监视器状态,这是一个例外。阅读
synchronized块和wait/notify。这与Lock无关,你不应该在这里使用它。 -
synchronized 是关于对象的隐式监视器,ReentrantLock 是关于对资源的互斥访问。
-
@Volodia 正如@Boris 所说:如果你想睡觉使用
Thread.sleep()如果你坚持滥用等待你必须写成long startTime = System.currentTimeMillis(); synchronized (lock) { while (System.currentTimeMillis() - startTime < 1000) { lock.wait(1000); } }
标签: java concurrency reentrantlock