当前位置:网站首页>JUC - thread interrupt and thread waiting and wakeup (locksupport)
JUC - thread interrupt and thread waiting and wakeup (locksupport)
2022-06-22 04:40:00 【It takes time for fish to find water】
Interrupt mechanism
What is interrupt mechanism ?
First
A thread should not be forced to interrupt or stop by other threads , It is A thread should stop itself , Decide your own destiny .
therefore ,Thread.stop, Thead.suspend, Thead.resumer It's been abandoned .
secondly
stay Java There is no way to stop a thread immediately , However, stopping threads is particularly important , For example, cancel a time-consuming operation .
therefore ,Java Provides a negotiation mechanism for stopping threads – interrupt , I.e. interrupt identification negotiation mechanism .
Interruption is just a mechanism for negotiation and cooperation ,Java There is no syntax added to interrupts in , The interruption process needs to be implemented by the programmer himself .
To interrupt a thread , You need to manually call the thread's interrupt Method , This method only sets the interrupt representation of the thread object to true
Then you need to write your own code to constantly detect the identification bit of the current thread , If true, Indicates that another thread requests this thread to interrupt
Each thread object has an interrupt identifier bit , Used to indicate whether a thread is interrupted ; The identification bit is true To interrupt , by false Means not interrupted ;
By calling the interrupt Method sets the identity of the thread to true; Can be invoked in other threads , You can also call it in your own thread .

- adopt volatile Variable implementation
- adopt AtomicBoolean Realization
- adopt Thread Class has its own interrupt api Example method implementation
public static void main(String[] args)
{
Thread t1 = new Thread(() -> {
while (true)
{
if(Thread.currentThread().isInterrupted())
{
System.out.println(Thread.currentThread().getName()+"\t isInterrupted() Changed to true, The program to stop ");
break;
}
System.out.println("t1 -----hello interrupt api");
}
}, "t1");
t1.start();
System.out.println("-----t1 The default interrupt flag bit of :"+t1.isInterrupted());
// Pause for milliseconds
try {
TimeUnit.MILLISECONDS.sleep(20); } catch (InterruptedException e) {
e.printStackTrace(); }
//t2 towards t1 Issue negotiation , take t1 The interrupt flag bit of is set to true hope t1 stop
new Thread(() -> {
t1.interrupt();
},"t2").start();
//t1.interrupt();
}
static AtomicBoolean atomicBoolean = new AtomicBoolean(false);
private static void m2_atomicBoolean()
{
new Thread(() -> {
while (true)
{
if(atomicBoolean.get())
{
System.out.println(Thread.currentThread().getName()+"\t atomicBoolean Changed to true, The program to stop ");
break;
}
System.out.println("t1 -----hello atomicBoolean");
}
},"t1").start();
// Pause for milliseconds
try {
TimeUnit.MILLISECONDS.sleep(20); } catch (InterruptedException e) {
e.printStackTrace(); }
new Thread(() -> {
atomicBoolean.set(true);
},"t2").start();
}
static volatile boolean isStop = false;
private static void m1_volatile()
{
new Thread(() -> {
while (true)
{
if(isStop)
{
System.out.println(Thread.currentThread().getName()+"\t isStop Changed to true, The program to stop ");
break;
}
System.out.println("t1 -----hello volatile");
}
},"t1").start();
// Pause for milliseconds
try {
TimeUnit.MILLISECONDS.sleep(20); } catch (InterruptedException e) {
e.printStackTrace(); }
new Thread(() -> {
isStop = true;
},"t2").start();
}
summary : When it comes to a thread , call interrupt When the method is used :
① If the thread is in Normal active state , The thread's interrupt flag will be set to true, That's it .
The thread with interrupt flag will continue to run normally , Unaffected .
therefore ,interrupt() It doesn't really interrupt threads , You need to cooperate with the called thread .
② If the thread is blocked ( For example, dealing with sleep、wait、join Equal state ), To call the current thread object in another thread interrupt Method , Then the thread will immediately exit the blocked state , And throw a interruptedException abnormal .
public static void main(String[] args)
{
// Example method interrupt() Just set the interrupt status bit of the thread to true, Thread will not be stopped
Thread t1 = new Thread(() -> {
for (int i = 1; i <=300; i++)
{
System.out.println("-----: "+i);
}
System.out.println("t1 Thread calls interrupt() The interrupt identifier of the following 02:"+Thread.currentThread().isInterrupted());
}, "t1");
t1.start();
System.out.println("t1 Thread default interrupt identifier :"+t1.isInterrupted());//false
// Pause for milliseconds
try {
TimeUnit.MILLISECONDS.sleep(2); } catch (InterruptedException e) {
e.printStackTrace(); }
t1.interrupt();//true
System.out.println("t1 Thread calls interrupt() The interrupt identifier of the following 01:"+t1.isInterrupted());//true
try {
TimeUnit.MILLISECONDS.sleep(2000); } catch (InterruptedException e) {
e.printStackTrace(); }
System.out.println("t1 Thread calls interrupt() The interrupt identifier of the following 03:"+t1.isInterrupted());
//????---false Interrupting an inactive thread does not have any effect .
//ps: Two seconds later, the thread has finished executing
}
In depth analysis of interrupted negotiation cases
public static void main(String[] args)
{
Thread t1 = new Thread(() -> {
while (true)
{
if(Thread.currentThread().isInterrupted())
{
System.out.println(Thread.currentThread().getName()+"\t " +
" Interrupt flag bit :"+Thread.currentThread().isInterrupted()+" The program to stop ");
break;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// Thread.currentThread().interrupt();// Without it , The program will not stop , Why in the exception , Call again ??
e.printStackTrace();
}
System.out.println("-----hello InterruptDemo3");
}
}, "t1");
t1.start();
// Pause the thread for a few seconds
try {
TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {
e.printStackTrace(); }
new Thread(() -> t1.interrupt(),"t2").start();
}
/** * 1 Interrupt flag bit , Default false * 2 t2 ----> t1 An interrupt negotiation was issued ,t2 call t1.interrupt(), Interrupt flag bit true * 3 Interrupt flag bit true, Normal condition , The program to stop ,^_^ * 4 Interrupt flag bit true, Abnormal situation ,InterruptedException, The interrupt status will be cleared , And will receive InterruptedException . Interrupt flag bit false * Cause infinite loop * * 5 stay catch In block , The interrupt flag bit needs to be set to again true,2 Call to stop the program OK */

Interruption is just a negotiation mechanism , Modifying the interrupt flag bit is nothing more , Not immediately stop interrupt
public static void main(String[] args)
{
// Test whether the current thread is interrupted ( Check interrupt flag ), Return to one boolean And clear the interrupt state ,
// The interrupt state has been cleared on the second call , Will return a false.
System.out.println(Thread.currentThread().getName()+"\t"+Thread.interrupted()); //false
System.out.println(Thread.currentThread().getName()+"\t"+Thread.interrupted());//false
System.out.println("----1");
Thread.currentThread().interrupt();// The interrupt flag bit is set to true
System.out.println("----2");
System.out.println(Thread.currentThread().getName()+"\t"+Thread.interrupted());//true
System.out.println(Thread.currentThread().getName()+"\t"+Thread.interrupted());//false
LockSupport.park();
Thread.interrupted();// Static methods
Thread.currentThread().isInterrupted();// Example method
}
Static methods interrupted The interrupt status will be clear ( From the source code ClearInterrupted by true)
Example method isInterrupted Will not be ( Incoming parameter ClearInterrupted by false)
summary :
Thread interrupt related methods :
public void interrupt(); interrupt() A method is an instance method
It notifies the target thread of an interrupt , Only set the interrupt flag bit of the target thread to true.
public boolean isInterrupted(); isInterrupted() Method is also an instance method
It determines whether the current thread is interrupted ( Check the interrupt flag bit ) And get the interrupt flag
public static boolean interrupted(), Thread Class static methods interrupted()
Returns the true value of the interrupt status of the current thread (boolean type ) After that, the interrupt status of the current thread will be set to false, After this method is called, the status of the interrupt flag bit of the current thread will be cleared ( Place the interrupt flag at false 了 ), Returns the current value and resets it to zero false
Thread wait and wake
LockSupport Is a basic thread blocking primitive used to create synchronization classes with other classes

LockSupport Medium park() and unpark() The functions of are to block threads and to unblock blocked threads
There are three ways for threads to wait for wakeup
- Use Object Of wait() Method to make the thread wait , Use Object Medium notify() Method wake up thread
- Use JUC In bag Condition Of await Method to make the thread wait , Use signal() Method wake up thread
- LockSupport Class can block the current thread and wake up the specified blocked thread
Object
private static void syncWaitNotify()
{
Object objectLock = new Object();
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {
e.printStackTrace(); }
synchronized (objectLock){
System.out.println(Thread.currentThread().getName()+"\t ----come in");
try {
objectLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"\t ---- Awakened ");
}
},"t1").start();
// Pause the thread for a few seconds
try {
TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {
e.printStackTrace(); }
new Thread(() -> {
synchronized (objectLock){
objectLock.notify();
System.out.println(Thread.currentThread().getName()+"\t ---- A notice ");
}
},"t2").start();
}
wait() and notify() Must be placed in a synchronized code block or synchronized method , And appear in pairs
Must be present wait() stay notify(), Otherwise, the program cannot be executed , Can't wake up
Condition
private static void lockAwaitSignal()
{
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {
e.printStackTrace(); }
lock.lock();
try
{
System.out.println(Thread.currentThread().getName()+"\t ----come in");
condition.await();
System.out.println(Thread.currentThread().getName()+"\t ---- Awakened ");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
},"t1").start();
// Pause the thread for a few seconds
try {
TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {
e.printStackTrace(); }
new Thread(() -> {
lock.lock();
try
{
condition.signal();
System.out.println(Thread.currentThread().getName()+"\t ---- A notice ");
}finally {
lock.unlock();
}
},"t2").start();
}
Condtion Thread waiting and wakeup methods in , You need to acquire the lock first
Be sure to await Again signal
LockSupport
LockSupport Class uses a method called Permit( The license ) To achieve Blocking and waking threads The function of , Each thread has a license (permit)
But with Semaphores Different , Licenses do not accumulate , At most one
park()/park(Object blocker): Blocking ,permit The license has no default direction , So at the beginning of the call park() Method will block the current thread , Until the current thread is issued by another thread permit,park The method will be awakened
unpark(Thread thread): Wake up the , call unpark(thread) After the method , Will be thread License for threads permit issue , Will wake up automatically park Threads , That is, in the previous blocking LockSupport.park() Method will immediately return
public static void main(String[] args)
{
Thread t1 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) {
e.printStackTrace(); }
System.out.println(Thread.currentThread().getName() + "\t ----come in"+System.currentTimeMillis());
LockSupport.park();
System.out.println(Thread.currentThread().getName() + "\t ---- Awakened "+System.currentTimeMillis());
}, "t1");
t1.start();
// Pause the thread for a few seconds
//try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(() -> {
LockSupport.unpark(t1);
System.out.println(Thread.currentThread().getName()+"\t ---- A notice ");
},"t2").start();
}
LockSupport There are no lock block requirements
The previous error wakes up first and then waits ,LockSupport Still support , First unpark Again park It is equivalent to having a pass in advance unpark,park There is no interception .park and unpark Must correspond to each other , because Licenses do not accumulate , At most one
summary
LockSupport Is a thread blocking tool class , All methods are static , The thread can be blocked at any location , After blocking, there is also a wake-up method for . in the final analysis ,LockSupport Called Unsafe Medium native Code (native The identified method calls the underlying C++、C Code ).
LockSupport Provided park() and unpark() Method to implement the process of blocking and unblocking threads
LockSupport And every thread that uses it has a license (permit) relation .
Each thread has an associated permit,permit At most one , Repeated calls to unpark It will not accumulate vouchers .
understand
Thread blocking requires consuming credentials (permit), There is only one voucher at most .
When calling park When the method is used
- If there is a certificate , It will consume the voucher directly and exit normally ;
- If there is no certificate , You have to block and wait for credentials to be available ;
and unpark On the contrary , It will add a voucher , But there can only be one voucher at most , Accumulation is invalid .
Why can we break through wait/notify The original calling sequence of ?
because unpark Got a certificate , Call later park Method , You can honestly rely on vouchers for consumption , So it won't block .
After the vouchers are issued first, they can be unblocked later .
Why wake up twice and block twice , But the end result will still block the thread ?
Because the maximum number of vouchers is 1, Two consecutive calls unpark And call once unpark The effect is the same , Only one voucher will be added ;
And call twice park But you need to consume two vouchers , If the certificate is not enough, it cannot be released .
边栏推荐
- 轻量级CNN设计技巧
- torch DDP Training
- 网页设计与制作期末大作业报告——动画家宫崎骏
- tinymce. Init() browser compatibility issue
- Internet of things UWB technology scheme, intelligent UWB precise positioning, centimeter level positioning accuracy
- window10无法访问局域网共享文件夹
- How SQL server generates change scripts
- Axios get parameter transfer splicing database fields
- System V IPC and POSIX IPC
- IDEA蓝屏的解决方案
猜你喜欢

Raspberry pie preliminary use

With this set of templates, it is easier to play with weekly, monthly and annual reports

Case driven: a detailed guide from getting started to mastering shell programming

JUC - 线程中断与线程等待、唤醒(LockSupport)

Circuit board layout and wiring precautions for analog / digital mixed signals

With these websites, do you still worry about job hopping without raising your salary?

Systematic arrangement | how many children's shoes have forgotten to be done carefully before the model development (practical operation)

PCM data format

About SSM integration, this is enough ~ (nanny level hands-on tutorial)

NFT mall building digital collection mall building digital collection market digital collection development company
随机推荐
浏览器--常用的搜索操作符大全--使用/实例
Bubble sort
Go learning notes
Ora - 15063: ASM discovered an insufficient number of Disks for diskgroup Recovery - - -
103. simple chat room 6: using socket communication
Spark - Executor 初始化 && 报警都进行1次
POSIX semaphore
网页设计与制作期末大作业报告——小众音乐网站
ln n, n^k , a^n, n!, The limit problem of n^n
解决Swagger2显示UI界面但是没内容
什么是论坛虚拟主机?如何挑选?
Calculation of audio frame size
JUC - 线程中断与线程等待、唤醒(LockSupport)
爬梯子&&卖卖股份的最佳时期(跑路人笔记)
High precision positioner formwork
IDEA藍屏的解决方案
天阳科技-宁波银行面试题【杭州多测师】【杭州多测师_王sir】
Use putty to configure port mapping to realize the access of the external network to the server
tinymce. Init() browser compatibility issue
网页设计与制作期末大作业报告——大学生线上花店