Java_16: Thread Interrupt

Keywords: Java network

Interruption of thread

1. Scenarios:

Assuming a 100M file is downloaded from the network, if the network speed is slow and the user is impatient, he or she may click Cancel during the download process, and the program will need to interrupt the execution of the download thread.

2. Common ways to interrupt threads:

1. Use marker bits

2.interrupt()

(1) If the current thread sleep,wait, or is blocked by other threads using join(), then when the thread's interrupt() method is called in another thread, join() and other methods will throw an InterruptedException exception immediately, and the target thread will end running as soon as it catches the exception
 (2) interrupt() cannot interrupt I/O and synchronized lock blockages
 About resetting interrupt flags:
isInterrupted() - Do not clear interrupt flags, current thread 
    public boolean isInterrupted() {//instance method, flag bits will not be reset
        return isInterrupted(false);
    }
interrupted()---- Clears the interrupt flag bit and becomes false, the current thread object that invokes the method
    public static boolean interrupted() {//static method, resets flag bits
        return currentThread().isInterrupted(true);
    }

3. Code

3.1 Set interrupt flags yourself

 class MyThreadTest extends Thread{
public  volatile boolean flag=true;
@Override
public void run() {

//1. Markers
while(flag){
        System.out.println(Thread.currentThread().getName()+"Whether to interrupt---"+
                        Thread.currentThread().isInterrupted()+
                        "------"+
                        Thread.currentThread().getState());
}
System.out.println("-----Trigger interrupt flag, interrupt---");
}

//Code for testing

@Test
public void test1() throws InterruptedException {
    MyThreadTest t = new MyThreadTest("Thread 1");
    t.start();

    Thread.sleep(1);
    t.flag = false;
}

3.2 Call interrupt()

interrupted()

Custom Thread Test
 class MyThread2 extends Thread {
@Override
public void run() {
                while (!isInterrupted()) {
                        System.out.println(Thread.currentThread().getName() + "Whether to interrupt---" +
                                        Thread.interrupted() +
                                        "------" +
                                        Thread.currentThread().getState());
                }
                System.out.println(Thread.currentThread().getName() + " end "+
                Thread.interrupted());
                System.out.println(Thread.currentThread().getName() + " end "+
                Thread.interrupted());

        }
    }

    //Code for testing

 @Test
public void test2() throws InterruptedException {
    MyThread2 t2=new MyThread2();
    t2.start();
    Thread.sleep(1);
    t2.interrupt();
}

Test directly on the main thread

public static void main(String[] args) throws InterruptedException {

Thread.currentThread().interrupt();
System.out.println(Thread.interrupted());
System.out.println(Thread.interrupted());
}
}

isInterrupted()

Custom Thread Class

class MyThread3 extends Thread {
        @Override
        public void run() {
                while (!isInterrupted()) {
                        System.out.println(Thread.currentThread().getName() + "Whether to interrupt---" +
                                        Thread.currentThread().isInterrupted() +
                                        "------" +
                                        Thread.currentThread().getState());
                }
                System.out.println(Thread.currentThread().getName()+" end "
                +Thread.currentThread().isInterrupted());
                System.out.println(Thread.currentThread().getName()+" end "
                +Thread.currentThread().isInterrupted());
        }
}

 @Test
public void test3() throws InterruptedException {
        MyThread3 t3=new MyThread3();
        t3.start();
        Thread.sleep(1);
        t3.interrupt();
}

Testing in the main thread

public static void main(String[] args) throws InterruptedException {
        Thread.currentThread().interrupt();
        System.out.println(Thread.currentThread().isInterrupted());
        System.out.println(Thread.currentThread().isInterrupted());
}
}

4. Summary and comparison:

1. It is best to use the isInterrupted() method to determine the interrupt flag because the flag bit will not be reset
2. Calling the interrupt() method on the target thread can request that a thread be interrupted, and the target thread gets whether it has been interrupted by detecting the isInterrupted() flag.
If the target thread is in a waiting state, it will catch InterruptedException;

3. If the target thread detects that isInterrupted() is true or captures InterruptedException, it should immediately terminate its own thread;

4. Use the volatile keyword correctly to judge by the flags;

The volatile keyword solves the visibility problem of shared variables between threads.

Posted by godster on Tue, 05 May 2020 17:59:10 -0700