简体   繁体   English

Java中的超时锁定

[英]Timed-out lock in java

I am looking for mechanism which will help me to implement following pattern (pseudocode):我正在寻找可以帮助我实现以下模式(伪代码)的机制:

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

    prepare();

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

    finish();
}

I need to limit invocations to execute to occur no more often, than some specified interval (for example, two minutes), but I do not want to block prepare or execute if it is not necessary.我需要限制要执行的调用的发生频率不超过某个指定的时间间隔(例如,两分钟),但是如果没有必要,我不想阻止准备执行 I am wondering if java supports any locking mechanism, which 'vanishes' after some time.我想知道 java 是否支持任何锁定机制,一段时间后“消失”。 Requirement is that, of course, lock does not pass through even if it's entered by the same thread, which locked it.要求是,当然,即使锁是由锁定它的同一个线程进入的,它也不会通过。

I was thinking about solution involving semaphore and TimerTask , or calculating deadline by myself and sleeping for superfluous time, but I wonder if something like this is already available.我正在考虑涉及 semaphore 和TimerTask 的解决方案,或者自己计算截止日期并睡多余的时间,但我想知道是否已经有这样的东西。

Thanks谢谢

No need for a special class:不需要特殊类:

synchronized(lock) {
   execute();
   Thread.sleep(120 * 1000)
}

The below will do basically you have a semphore which will only let you access if there is a permit available, I this case zero permits.下面基本上会做你有一个信号灯,它只会让你在有许可证可用的情况下访问,我在这种情况下是零许可证。 So it will try for 2000 seconds before finally giving up ->所以它会尝试 2000 秒才最终放弃 ->

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

Thread.sleep is a lame and low level way of doing it. Thread.sleep是一种蹩脚且低级的方式。 Not recommended不建议

As Marko says , you very likely want to do this by handing the work off to a scheduler of some sort, rather than blocking the thread. 正如 Marko 所说,您很可能希望通过将工作交给某种调度程序而不是阻塞线程来做到这一点。

But if you do want to do this, i would suggest that you do it by recording a timestamp on exiting the critical section, and having entering threads wait for a period after that to pass.但是,如果您确实想这样做,我建议您通过在退出临界区时记录时间戳来完成,并让进入线程等待一段时间后通过。 Something like:就像是:

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

}

你可以使用睡眠

sleep(1000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM