编程知识 cdmana.com

The difference between interrupt and park in Java

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 out InterruptedException 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 a InterruptedException 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 , however ReentrantLock 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 .

版权声明
本文为[Zhouer duck]所创,转载请带上原文链接,感谢

Scroll to Top