Maciek
Maciek

Reputation: 1716

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. 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.

Thanks

Upvotes: 3

Views: 4078

Answers (4)

Tom Anderson
Tom Anderson

Reputation: 47183

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.

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

}

Upvotes: 1

Jatin
Jatin

Reputation: 31724

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

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. Not recommended

Upvotes: 2

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136002

No need for a special class:

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

Upvotes: 1

Shamis Shukoor
Shamis Shukoor

Reputation: 2515

You could use the sleep

sleep(1000);

Upvotes: 0

Related Questions