1

スレッドが によってロックされたクリティカル セクションにある間、スレッドを何らかの方法で 1 秒間停止する必要がありますReentrantLock

私のコードは次のとおりです。

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)ます。

4

1 に答える 1

0

lock.wait(1000)オブジェクトが正しい方法でロックされていないロック b/c 内で呼び出すと、例外が発生します。それは事です。

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);

または上記のいくつかのバリエーション。

幸運を。

于 2014-05-21T03:58:20.760 に答える