Locks In Java [Part -3] — LockSupport
we are going to discuss about the lockSupport class in java which is a part of the concurrent package under the lock package.
- it is a support class which is used to create lock and other synchronization classes in java
- it provides alternative for the deprecated method of thread suspend() and resume().
- it is used for creating higher level of synchronisation utilities and is not frequently used for most applications while dealing with concurrency.
- Under the Hood , it used Unsafe class in java which is build to be used for the secure java code for doing the operations.
- this class cannot be instantiated and it contains static methods to be used.
Methods
lets discuss these methods and what are there use-cases one by one
setCurrentBlocker
it is used to set a reference into a java variable. so here the thread t is added with a reference to the object arg we have added here at a offset value.
park and unpark are native methods so they are implemented in C / C++
lets first discuss the park method and its time variations and then we will see the unpark.
park
this method uses a permit ( same as semaphore) which is used to block the thread to proceed further. here it is a kind of binary semaphore which basically 1 means that thread can go further and 0 means it is blocked, so on calling park if the current state was 1 then it becomes 0 so the thread gets blocked.
here in order to release the thread from blockage one of the following scenarios should occur.
- some other thread calls the unpark method on this thread
- some other thread interrupts the current thread
- some spuriously ( for no reason) returns
- when we use parkNanos we add a time limit for it to be blocked so if that time elapses then it is unblocked, similary for parkUntill , untill the time is equal to the given value it is blocked.
unpark
unpark simply releases the permit and makes the thread available for further processing.
once unpark is called for a thread and repetitive calls wont do any effect on the thread state.
it has to be called by some other thread for the current thread to unblock.
example
lets see the use case with help of a example where we are trying to add a counter value in an array and we block the first thread and get it released by another thread to see that how threads are blocked and released using park and unpark.
package com.example.demo.learning;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.LockSupport;
public class LockSupportExample {
public static void main(String[] args) throws InterruptedException {
List<Integer> counters = new ArrayList<>();
final int[] count = {0};
Thread t1 = new Thread(() -> {
LockSupport.park();
while (true){
try {
Thread.sleep(1_000L);
counters.add(count[0]);
count[0]++;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
//throw new RuntimeException(e);
}
}
});
t1.start();
Thread t2 = new Thread(() -> {
try {
Thread.sleep(2_500L);
}
catch (InterruptedException e){
Thread.currentThread().interrupt();
}
LockSupport.unpark(t1);
});
t2.start();
Thread.sleep(5_000L);
t1.interrupt();
System.out.println(counters);
}
}
now here lets see the scenario
similarly we can see use parkNanos , parkUntill to release the permit automatically instead of calling the unpark method by some other thread.
Final Thoughts
although we have other methods to block a thread using wait() and join() and we should avoid using locksupport park and unpark for that as its low-level and can cause issues.
the one good thing about using park is that we dont need to enter any synchronised block to disable the thread , thus avoiding the extra refresh of all the variables which happens when we do it by entering the sync block. although this optimisation is hardly needed.
thanks for reading 😀!! do share in comments if you find any more use cases or anything which is missing or wrong here , would love to learn.
code : https://github.com/avinashsoni9829/Threading/blob/main/locks/LockSupportExample.java