Usage of LockSupport in Java concurrent programming series
- 2021-12-13 07:59:30
- OfStack
1. What is LockSupport?
LockSupport is the basic thread blocking primitive for creating locks and other synchronization classes
2. Two basic API
LockSupport
Two basic types of API are provided:
block thread class: 1 is usually a method name beginning with pack, pack * (...)
The pack method has two overloaded versions: blocker is an object that specifies which object to block. If you don't know, by default, the lock object itself this is blocker
public static void park();
public static void park(Object blocker);
Expand:
parkNanos
Function
public static void parkNanos(Object blocker, long nanos) {
if (nanos > 0) {
// Gets the current thread
Thread t = Thread.currentThread();
// Settings Blocker
setBlocker(t, blocker);
// Get the license and set the time
UNSAFE.park(false, nanos);
// Set permissions, reset blocker For null , avoid unpack Obtained by the blocker For the previously set
setBlocker(t, null);
}
}
The nanos parameter represents the relative time, indicating how long to wait
parkUntil
Function: Indicates that the current thread is disabled before the specified time limit. deadline parameter indicates absolute time and specified time
public static void parkUntil(Object blocker, long deadline) {
// Gets the current thread
Thread t = Thread.currentThread();
// Settings Blocker
setBlocker(t, blocker);
UNSAFE.park(true, deadline);
// Settings Blocker For null
setBlocker(t, null);
}
unBlock
Thread class:
unpack(Thread)
The unpack method is used to release the license, specifying that the thread can continue to run.
3. LockSupport essence
LockSupport is a licensed semaphore mechanism, pack is consumed, unpack is put in, and only one is put in, which is not accumulated. For example, if you call unpack and put one semaphore into it, you will not accumulate the semaphore if you call it several times, and you will consume it after calling pack
4. Example of LockSupport
Example: How to control two threads to print 1, 2, 3, 4, 5, 6, …
import java.util.concurrent.locks.LockSupport;
public class LockSupportExample {
private static final int total = 10;
private static int i = 0;
static Thread t1 , t2;
public static void main(String[] args) {
t1 = new Thread(() ->{
while (i < total) {
System.out.println("t1:" + (++i));
LockSupport.unpark(t2);
LockSupport.park();
}
});
t2 = new Thread(() -> {
while (i < total) {
LockSupport.park();
System.out.println("t2:" + (++i));
LockSupport.unpark(t1);
}
});
t1.start();
t2.start();
}
}
Print:
t1: 1
t2: 2
t1:3
t2:4
t1:5
t2:6
t1:7
t2:8
t1:9
t2:10
5. LockSupport source code
public class LockSupport {
// Hotspot implementation via intrinsics API
private static final sun.misc.Unsafe UNSAFE;
private static final long parkBlockerOffset;
private static final long SEED;
private static final long PROBE;
private static final long SECONDARY;
static {
try {
// Get Unsafe Instances
UNSAFE = sun.misc.Unsafe.getUnsafe();
// Of the thread class class Object
Class<?> tk = Thread.class;
// Get Thread Adj. parkBlocker Memory offset address of field
parkBlockerOffset = UNSAFE.objectFieldOffset
(tk.getDeclaredField("parkBlocker"));
// Get Thread Adj. threadLocalRandomSeed Memory offset address of field
SEED = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSeed"));
// Get Thread Adj. threadLocalRandomProbe Memory offset address of field
PROBE = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomProbe"));
// Get Thread Adj. threadLocalRandomSecondarySeed Memory offset address of field
SECONDARY = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocalRandomSecondarySeed"));
} catch (Exception ex) { throw new Error(ex); }
}
}
pack method source code:
public static void park(Object blocker) {
// Gets the current thread
Thread t = Thread.currentThread();
// Settings Blocker
setBlocker(t, blocker);
// Obtain a license
UNSAFE.park(false, 0L);
// Reset this setting after rerun Blocker For null , avoid unpack Get to on 1 Setting of setBlocker(t, blocker);
setBlocker(t, null);
}
unpack source code:
public static void unpark(Thread thread) {
if (thread != null) // Thread is not empty
UNSAFE.unpark(thread); // Release the thread permission
}
It can be seen that both the source code of pack and the source code of unpack are implemented through the underlying api of Unsafe
sun.misc.Unsafe
Tool classes that can directly perform underlying unsafe operations
It mainly provides the following operations:
Thread Suspend and Resume CAS operation Manipulating object properties Manipulate array elements Direct manipulation of memory
Summarize
This article is here, I hope to give you help, but also hope that you can pay more attention to this site more content!