1. Background
The interviewer asked how to pause a thread
Tell me about your understanding of park
2. Code
package com.ldp.demo01; import com.common.MyThreadUtil; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.locks.LockSupport; /** * @author Blog emperor posture * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 02/01 10:58 * @description <p> * park & unpark Compared with wait & notify * 1.wait,notify NotifyAll and notifyAll must be used together with Object Monitor, but park and unpark do not * 2.park & unpark It blocks and wakes up threads in the unit of threads, while notify can wake up only one waiting thread randomly. notifyAll wakes up all waiting threads, which is not so accurate * 3.park & unpark You can unpark first, but wait & notify cannot notify first * </p> */ @Slf4j public class Test04UnPark { /** * 1.park at unPark first * 2.unPark first in park --- (it will make the first park invalid) * <p> * park Understanding (very important) * <p> * Each thread has its own Parker object, * It consists of three parts_ Counter_ cond (concentrator, which is equivalent to lounge) and_ Mutex (mutex) * <p> * Make an analogy * Thread is like a traveler, Parker is like his backpack_ cond is like a tent in a backpack_ counter is like the spare dry food in the backpack (0 is exhausted and 1 is sufficient) * <p> * Call park to see if you need to stop and rest * If the spare dry food is exhausted (_counter=0), enter the tent to rest * If there is enough spare dry food (_counter=1), you don't need to stay and move on * <p> * <p> * Calling unpark is like replenishing dry food (no matter how many times you call it, you can only replenish it once) * If the thread is still resting in the tent, wake up and let him move on * If the thread is running at this time, the next time he calls park, he will only consume the spare dry food (i.e. the dry food supplemented by unpark this time), and there is no need to stay and move on * Because the backpack space is limited, calling unpark for many times will only supplement one spare dry food * <p> * <p> * The direct explanation is: * Each thread has its own Parker object, * It consists of three parts_ Counter_ cond (concentrator, which is equivalent to lounge) and_ Mutex (mutex) * <p> * <p> * When calling park to pause the thread * If unpark is not called before, the current thread will be suspended directly * If unpark is invoked before that, the thread continues to run, which is equivalent to the invalid park. * <p> * <p> * When you call unpark and want the thread to continue running * If the thread is in a suspended state, the thread is awakened to start execution; * If the thread is already running, the thread will continue to run, and will remember that this unpark will be invalid the next time the thread parks * When unpark is called multiple times, only one unpark is valid * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { log.info("t1......1"); // 2 Continue in seconds MyThreadUtil.sleep(2); // Pauses the current thread LockSupport.park(); log.info("t1......2"); LockSupport.park(); log.info("t1......3"); LockSupport.park(); log.info("t1......4"); }, "t1"); t1.start(); // 2 Continue in seconds // MyThreadUtil.sleep(2); // Return to running status LockSupport.unpark(t1); log.info("unpark......1"); LockSupport.unpark(t1); log.info("unpark......2"); } }
3. Differences
Compare Park & unpark with wait & notify
1.wait, notify and notifyAll must be used together with Object Monitor, while park and unpark do not
2. Park & unpark blocks and wakes up threads by thread, while notify can wake up only one waiting thread randomly. notifyAll wakes up all waiting threads, which is not so accurate
3. Park & unpark can unpark first, but wait & notify cannot notify first
4. Principle understanding
Each thread has its own Parker object,
It consists of three parts_ Counter_ cond (concentrator, which is equivalent to lounge) and_ Mutex (mutex)
4.1. Figurative understanding
Thread is like a traveler, Parker is like his backpack_ cond is like a tent in a backpack_ counter is like the spare dry food in the backpack (0 is exhausted and 1 is sufficient)
Call park to see if you need to stop and rest
If the spare dry food is exhausted (_counter=0), enter the tent to rest
If there is enough spare dry food (_counter=1), you don't need to stay and move on
Calling unpark is like replenishing dry food (no matter how many times you call it, you can only replenish it once)
If the thread is still resting in the tent, wake up and let him move on
If the thread is running at this time, the next time he calls park, he will only consume the spare dry food (i.e. the dry food supplemented by unpark this time), and there is no need to stay and move on
Because the backpack space is limited, calling unpark for many times will only supplement one spare dry food
4.2. Direct interpretation
Each thread has its own Parker object,
It consists of three parts_ Counter_ cond (concentrator, which is equivalent to lounge) and_ Mutex (mutex)
When calling park to pause the thread
If unpark is not called before, the current thread will be suspended directly
If unpark is invoked before that, the thread continues to run, which is equivalent to the invalid park.
When you call unpark and want the thread to continue running
If the thread is in a suspended state, the thread is awakened to start execution;
If the thread is already running, the thread will continue to run, and will remember that this unpark will be invalid the next time the thread parks
When unpark is called multiple times, only one unpark is valid