The java.util.concurrent.locks.The lock provides an interface that can be implemented and used for locking critical sections when working in a multithreaded environment in a JVM.
Similarly, ILock extends the interface to provide a distributed version of Java Lock. It provides similar functions: lock, unlock, tryLock
But a major difference between ILock and Java Lock is that while Java Lock provides protection of critical sections from threads in a single JVM, ILock provides synchronization for threads in a single JVM as well as multiple JVMs.
ILock has one synchronous backup meaning that if we have a setup where we have, say, 5 JVMs running, only two JVMs will hold this variable.
Let’s look at an example of the useful functions.
Acquiring and Releasing Lock
Let’s say we execute the following code on two JVMs.
Example
public static void main(String... args) throws IOException, InterruptedException {
//initialize hazelcast instance
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
// create a lock
ILock hzLock = hazelcast.getLock("lock_1");
IAtomicLong counter = hazelcast.getAtomicLong("counter");
// acquire lock
hzLock.lock();
System.out.println("Acquiring Lock");
try{
Thread.sleep(5000);
System.out.println("Incrementing Counter");
counter.incrementAndGet();
System.out.println("Counter: " + counter.get());
}
finally {
// release lock
System.out.println("Lock Released");
hzLock.unlock();
}
System.exit(0);
}
Output
The output of the above function shows that the second JVM was able to acquire the lock only after the first JVM released the lock.
Acquired Lock
Incrementing Counter
Counter: 1
Lock Released
Acquired Lock
Incrementing Counter
Counter: 2
Lock Released
Using tryLock instead of Lock
To reduce the chances of deadlock, it is recommended to use tryLock(timeout, unit) method instead lock(). By default, the lock() has a timeout of 5 mins and throws OperationTimeoutException exception if lock is not acquired in that timespan. tryLock instead returns a Boolean based on whether the lock is acquired or not in the provided timespan.
Example
Let’s execute the following code on two JVMs.
public static void main(String... args) throws IOException, InterruptedException {
//initialize hazelcast instance
HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
// create a lock
ILock hzLock = hazelcast.getLock("lock_1");
// acquire lock
if(hzLock.tryLock(2000, TimeUnit.SECONDS)) {
System.out.println("Acquired Lock");
Thread.sleep(5000);
System.out.println("Lock Released");
hzLock.unlock();
}
else
System.out.println("Couldn't acquire lock");
System.exit(0);
}
Output
The output for the code would be −
Acquired Lock
Couldn't acquire lock
Lock Released
Good practices and know-hows
- While acquiring locks can be very useful, it is recommended to keep the critical section as short as possible. This ensures that the performance does not degrade and it also reduces the chances of a deadlock.
- If a member (which has acquired) goes down, the lock is automatically released and is up for grabs for other members.
- The lock is rentrant; it ensures that the same thread can acquire a lock multiple times without causing a deadlock.
Useful Methods
Sr.No | Function Name & Description |
1 | lock() Acquire the provided lock instance so that no other thread can acquire it. If unavailable, it waits indefinitely till the lock is acquired. |
2 | unlock() Release the acquire lock |
3 | tryLock(long time, TimeUnit unit) Try to acquire a lock in the given time window. Return true if the lock is acquired, else false. |
4 | isLocked() Check if the lock is already acquired by some other thread |
Pingback: เทคนิคบาคาร่า ทำกำไรได้ทุกวัน
Pingback: Anapolon Kaufen
Pingback: 티비위키
Pingback: 뉴토끼