3

次のパターン (疑似コード) を実装するのに役立つメカニズムを探しています。

TimeoutLock lock = new TimeoutLock();
while(condition) {

    prepare();

    lock.enter(); //cannot enter until specified lock timeout elapses
    execute();
    lock.lockFor(2 minutes);

    finish();
}

実行するための呼び出しが指定された間隔 (たとえば 2 分) よりも頻繁に発生しないように制限する必要がありますが、必要でない場合は準備または実行をブロックしたくありません。Java が、しばらくすると「消える」ロック機構をサポートしているかどうか疑問に思っています。もちろん、lock をロックしたのと同じスレッドによって入力されたとしても、lock が通過しないことが要件です。

セマフォとTimerTaskで解決したり、デッドラインを自分で計算して無駄な時間を寝かせたりと考えていたのですが、このようなものはすでにあるのでしょうか。

ありがとう

4

4 に答える 4

1

以下は基本的にあなたが利用可能な許可がある場合にのみあなたがアクセスできるようにするセマフォを持っていることを行います、私はこの場合ゼロ許可です。したがって、最終的にあきらめる前に、2000秒間試行します->

Semaphore s = new Semaphore(0);
Object lock = new Object();
 synchronized(lock)
{
execute();
s.tryAcquire(2,TimeUnit.Minutes)
}

Thread.sleepそれを行うには、不完全で低レベルの方法です。推奨されません

于 2012-11-22T18:28:32.773 に答える
1

特別なクラスは必要ありません:

synchronized(lock) {
   execute();
   Thread.sleep(120 * 1000)
}
于 2012-11-22T18:24:08.240 に答える
1

Marko が言うように、スレッドをブロックするのではなく、何らかのスケジューラーに作業を渡すことで、これを実行したいと思うでしょう。

ただし、これを実行したい場合は、クリティカル セクションを終了する際にタイムスタンプを記録し、スレッドに入るときにそれが経過するまで待機させることをお勧めします。何かのようなもの:

public class TimeoutLock {

    private boolean held;
    private long available;

    public void enter() throws InterruptedException {
        acquire();
        long pause;
        while ((pause = available - System.currentTimeMillis()) > 0L) {
            Thread.sleep(pause);
        }
    }

    private synchronized void acquire() throws InterruptedException {
        while (held) {
            wait();
        }
        held = true;
    }

    public synchronized void lockFor(long period) {
        held = false;
        available = System.currentTimeMillis() + period;
        notify();
    }

}
于 2012-11-22T19:02:29.277 に答える
0

あなたは睡眠を使うことができます

sleep(1000);
于 2012-11-22T18:15:48.127 に答える