【问题标题】:How to wait for specified time in critical section locked by ReentrantLock?如何在 ReentrantLock 锁定的临界区等待指定时间?
【发布时间】: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/notify API 的一部分——它继承自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


【解决方案1】:

在锁 b/c 内调用 lock.wait(1000) 时出现异常,您没有以正确的方式锁定对象。这是一回事。

synchronized(object) {
  object.wait(1000);
}

如果你锁定了object 的监视器,这很有效。 ReentrantLock.lock() 以不同的方式工作。一切都没有丢失!您可以使用Thread.sleep()LockSupport.parkNanos() 让您的线程在临界区内休眠。

如果您需要处理虚假唤醒,则需要一个循环。

long waitStart = System.nanoTime();
long waitTime = TimeUnit.SECONDS.toNanos(1);
do {
  LockSupport.parkNanos(waitTime);
  waitTime = waitTime - (System.nanoTime() - waitStart);
} while(waitTime > 0);

或者上面的一些变体。

祝你好运。

【讨论】:

  • 我认为删除waitTime = wait...} while (System.nanoTime() - waitStart < waitTime); 会更容易理解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
相关资源
最近更新 更多