12

Java マルチスレッドでデッドロック状態を回避する戦略の 1 つは、タイムアウトを使用することです。1 つのスレッドが 1 つのリソースでロックを取得し、別のリソースでロックを待機しているとします。リソース 2 のロックを取得できない場合は、一定の時間が経過した後、リソース 2 のロックの待機を停止する必要があります。また、resource1 のロックを解放する必要があります。したがって、デッドロックは回避されます。

しかし、それを Java で実装する方法は? ロックを明示的に「解放」する方法は? ロック待ちのタイムアウトの定義方法。

正確なJavaコマンドと構文は何ですか. こんにちは世界的な例を教えてください。

4

4 に答える 4

10

以下は、異なる順序でロックを取得しようとする 2 つのロックと 2 つのスレッドを使用した不自然な例です。タイムアウトがないと、コードはデッドロックします。

public static void main(String[] args) throws Exception {
    final ReentrantLock lock1 = new ReentrantLock();
    final ReentrantLock lock2 = new ReentrantLock();
    Runnable try1_2 = getRunnable(lock1, "lock 1", lock2, "lock 2");
    Runnable try2_1 = getRunnable(lock2, "lock 2", lock1, "lock 1");
    new Thread(try1_2).start();
    new Thread(try2_1).start();
}

private static Runnable getRunnable(final ReentrantLock lock1, final String lock1Name, final ReentrantLock lock2, final String lock2Name) {
    return new Runnable() {
        @Override
        public void run() {
            try {
                if (lock1.tryLock(1, TimeUnit.SECONDS)) {
                    System.out.println(lock1Name + " acquired in thread " + Thread.currentThread());
                    if (lock2.tryLock(1, TimeUnit.SECONDS)) {
                        System.out.println(lock2Name + " acquired in thread " + Thread.currentThread());
                        Thread.sleep(2000);
                    } else {
                        System.out.println("Could not acquire "+lock2Name + " in thread " + Thread.currentThread());
                        lock1.unlock();
                        System.out.println(lock1Name + " released in thread " + Thread.currentThread());
                    }
                } else {
                    System.out.println("Could not acquire " + lock1Name + " in thread " + Thread.currentThread());
                }
            } catch (InterruptedException e) {
                //you should not ignore it
            } finally {
                if (lock1.isHeldByCurrentThread()) lock1.unlock();
                if (lock2.isHeldByCurrentThread()) lock2.unlock();
            }
        }
    };
}
于 2012-12-06T10:35:14.983 に答える
3

Javaでロック

Use tryLock(timeout, timeunits);

指定された待機時間内に解放され、現在のスレッドが中断されていない場合、ロックを取得します。ロックが利用可能な場合、このメソッドはすぐに値を返します。true

ロックが使用できない場合、現在のスレッドはスレッド スケジューリングの目的で無効になり、次の 3 つのいずれかが発生するまで休止状態になります。

ロックは現在のスレッドによって取得されます。

または 他のスレッド が現在のスレッドに割り込んでおり、ロック取得の中断がサポートされています。

または 指定された待ち時間が経過する

于 2012-12-06T10:25:10.753 に答える
3

これが役に立ちますように、

Lock lock = null;
lock=....;
if (lock.tryLock(15L, TimeUnit.SECONDS)) {
    try {
       ........
    } finally {
        lock.unlock();
    }
} else {
      // do sumthing
}
于 2012-12-06T10:30:47.263 に答える