头图

LockSupport utility class

LockSupport rt.jar package is a utility class, its main role is to suspend and wake up threads, and class is to create a basis for locks and other synchronization classes .

The LockSupport class and each thread that uses it are associated with a license, by default calling the methods of the LockSupport class does not hold a license. LockSupport is implemented using the Unsafe class.

The main methods in LockSupport are described below.

void park()

If the associated license has been obtained before calling the park() method, it will return immediately after the call, otherwise it will be prohibited from participating in the scheduling of the thread, that is, it will be blocked and suspended.

The following code will eventually only output "start", and then the current thread is suspended, because the calling thread does not hold a license by default.

public static void main(String[] args) throws Exception {
        System.out.println("开始...");
        LockSupport.park();
        System.out.println("结束...");
}
//结果:
//开始...

When other threads call the unpark(Thread thread) method with the currently blocked thread as a parameter, the thread blocked by calling the park() method will be returned. When another thread calls the interrupt() method of the blocked thread, sets the interrupt flag or the thread is spuriously awakened, the blocked thread will also be returned.

requires attention:

  1. When the blocked thread calling the park() method is interrupted by other threads and returns, InterruptedException will not be thrown.
  2. The license is one-time. For example, thread B calls the unpark() method three times in a row. When thread A calls the park() method, the license will be used up. If thread A calls the park() method again, it will enter the waiting state.

void unpark(Thread t)

When a thread calls the unpark() method, if the incoming parameter thread does not hold a license, let the incoming thread hold a license; if the thread is suspended after calling park() before, call unpark() It will wake up the thread; if the thread has not called park() before, after calling the unpark() method, it will return immediately when the park() method is called.

public static void main(String[] args) throws Exception {
        System.out.println("开始...");
        LockSupport.unpark(Thread.currentThread());
        LockSupport.park();
        System.out.println("结束...");
}
//输出结果:
//开始...
//结束...

See the following code to deepen your understanding of park and unpark.

public static void main(String[] args) throws Exception {
        Thread t = new Thread(() -> {
            System.out.println("子线程开始...");
            //挂起自己
            LockSupport.park();
            System.out.println("子线程结束...");
        });
        t.start();
        Thread.sleep(1000);
        System.out.println("主线程开始调用unpark");
        LockSupport.unpark(t);
}
//输出结果:
//子线程开始...
//主线程开始调用unpark
//子线程结束...

This code first creates a child thread t, and calls the park() method after the child thread is started. Since the child thread does not hold a license by default, it suspends itself.

After the main thread sleeps for 1 second, call unpark() and pass in the child thread t. This is to allow the child thread to obtain the license, and then the blocked park() in the child thread will return.

void parkNanos(long nanos)

Similar to the park() method, if the license has been obtained, the method will return immediately after calling this method. The difference is that if the license is not obtained, the calling thread will be suspended and return automatically after nanos time.

In addition, the park() method also supports the void park (Object blocker) method with a blocker parameter. When the thread is blocked and suspended by calling the park() method without a license, the blocker object Logged inside this thread. Generally used to identify blocking objects, which are mainly used for troubleshooting and system monitoring .

void parkNanos(Object blocker,long nanos) Compared with the previous method, this method increases the timeout time.

void parkUntil(Object blocker,long deadline)

public static void parkUntil(Object blocker, long deadline) {
        Thread t = Thread.currentThread();
        setBlocker(t, blocker);
        UNSAFE.park(true, deadline);
        setBlocker(t, null);
}

The time unit of the parameter deadline is ms. The difference between this method and parkNanos(Object blocker, long nanos) is that the latter waits nanos seconds from the current time, while the former specifies a time point, such as 2022-01-19 12: 00:00.

Summarize

Compared with the wait/notify mechanism of the Object class, park/unpark has two advantages:

  • Taking thread as the operation object is more in line with the intuitive definition of blocking thread
  • The operation is more accurate, and a certain thread can be woken up accurately (notify wakes up a thread randomly, notifyAll wakes up all waiting threads), which increases flexibility

神秘杰克
765 声望383 粉丝

Be a good developer.