For many new to programming , For the two concepts of thread interruption and thread blocking , It's often confused , Simply think that the concept of thread interrupt and thread blocking is consistent , It is the stop of the running state of the value thread . In fact, this view is wrong , There was a big difference between the two before , The differences between the two are highlighted below .
Thread the interrupt
Before a thread ends normally , If forced to terminate , Then there may be some serious consequences , Imagine if a thread now holds a synchronization lock , Then it is forced to sleep without releasing the lock resource , Then this causes other threads to lose access to the synchronized code block . So we can see in Java It's similar to Thread#stop()
The method is marked as @Deprecated
.
In view of the above situation , We can't terminate the thread directly , But sometimes you have to stop the thread from running some code , Now we have to have a mechanism to let the thread know it's time to stop .Java For us to provide a more elegant approach , That is, it can be done through Thread#interrupt()
Give a flag bit to the thread , Let the thread decide for itself what to do .
The next step is to delay with code interrupt()
The role of :
public class InterruptDemo {
static class MyThread implements Runnable {
@Override
public void run() {
for (int i= 0; !Thread.currentThread().isInterrupted() && i < 200000; i++) {
System.out.println(Thread.currentThread().getName() + ":i = " + i);
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread myThread = new Thread(new MyThread());
myThread.start();
// Let the thread run for a while
Thread.sleep(5);
myThread.interrupt();
// wait for myThread Operation stop
myThread.join();
System.out.println("end");
}
}
The results of the above code are as follows :
You can see , The current thread does not press for The end of the loop 20000 Go for a run , But after being interrupted , Stop the current for loop . So we can use interrupt Configure the thread to use , Make the thread stop at a certain position .
However, it may cause some doubts here , Because it looks like here , The current thread seems to be blocked , It's not , We can use the following code to demonstrate :
public class InterruptDemo {
static class MyThread implements Runnable {
@Override
public void run() {
for (int i= 0; i < 200000; i++) {
System.out.println(Thread.currentThread().getName() + ":i = " + i);
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread myThread = new Thread(new MyThread());
myThread.start();
// Let the thread run for a while
Thread.sleep(5);
myThread.interrupt();
// wait for myThread Operation stop
myThread.join();
System.out.println("end");
}
}
The above code runs as follows :
so , The thread prints all the way to 20000, Push out the thread after execution , It didn't interrupt somewhere as we expected . So we can draw a conclusion : Simple to use interrupt()
The interrupt thread method does not stop the currently running thread , You need to cooperate with other methods to stop the thread correctly .
After understanding the basic concept of interruption , There are other points that need to be paid attention to when the thread is interrupted :
- Set thread interrupt , Call in thread
wait()
、join()
、slepp()
One of the methods , Will throw outInterruptedException
abnormal , And the interrupt flag bit is cleared , Reset to false; - When a thread is blocked , For example, one of the above three methods is called , Then call it at this time
interrupt()
Method , There will also be aInterruptedException
abnormal . Because there is no possession CPU Can't set the interrupt status position for itself ; - Try to get an internal lock operation ( Enter a
synchronized
block ) It can't be interrupted , howeverReentrantLock
Support interruptible acquisition mode :tryLock(long time, TimeUnit unit)
; - When code calls need to throw a
InterruptedException
, After capture , Or keep throwing it up , Either reset the interrupt state , This is the safest way to do it .
Thread blocking
That's the end of thread interruption , It's just a marker bit , It doesn't really stop the thread , So, let's talk about how to really stop the thread .
For this question ,Java Provides a lower level concurrency tool class in :LockSupport
, There are two core methods in this class :park(Object blocker)
as well as unpark(Thread thred)
, The former means blocking the specified thread , The latter means to wake up the specified thread .
// java.util.concurrent.locks.LockSupport
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker);
UNSAFE.park(false, 0L);
setBlocker(t, null);
}
public static void unpark(Thread thread) {
if (thread != null)
UNSAFE.unpark(thread);
}
The method in Java On the language level, it is relatively simple , In the end, it's called UNSAFE Medium native Method . What really matters to the bottom needs to be understood JVM Source code , I don't want to do too much introduction here . But we can use a simple example to demonstrate these two methods :
public class LockSupportDemo {
static class MyThread implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Start execution ");
LockSupport.park();
System.out.println(Thread.currentThread().getName() + " end of execution ");
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new MyThread(), " Threads :MyThread");
thread.start();
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " The main thread is executing ");
LockSupport.unpark(thread);
System.out.println(Thread.currentThread().getName() + " End of main thread execution ");
}
}
The execution result of the above code is :
Threads :MyThread Start execution
main The main thread is executing
Threads :MyThread end of execution
main End of main thread execution
You can see ,myThread
The thread stops after it starts executing , Wait until the main thread calls again LockSupport.unpark(thread)
After that, we'll start again .