Stop, pause, and resume threads in Java

Conceptual knowledge

Brief introduction

The APIs corresponding to the Thread Thread for suspend, resume and stop operations are suspend(), resume() and stop(). But these APIs are out of date, which is not recommended. The main reasons why it is not recommended are:
Take the suspend() method as an example. After the call, the thread will not release the occupied resources (such as locks), but occupy the resources and enter the sleep state, which is easy to cause deadlock problems.
Similarly, the stop() method does not guarantee the normal release of the thread's resources when terminating a thread. Usually, the thread is not given the opportunity to complete the resource release work, so the program may work in an uncertain state. Because of the side effects of the suspend(), resume() and stop() methods, these methods have been marked as expired methods that are not recommended.

Stop thread

1.stop This is not recommended because it has expired. Stop is equivalent to the kill process of Linux, which is very violent. I don't know if the user still has a request that has not been processed. If I force it to close, there may be unpredictable problems. appear

2.interrupt Elegant interruption, it is recommended to use this
first to prevent subsequent requests from coming in, and at the same time wait for the currently executing process to be processed before stopping the thread

3…By means of instructions, volatile boolean isStop = false;

Volatile is visible to threads.

4…Thread.interrupted();

To reset the thread with the set interrupt flag is to change interrupted to false.

There are three methods related to thread interruption:

public void Thread.interrupt() //Interrupt the thread
public boolean Thread.isInterrupted() //Determine whether it is interrupted
public static boolean Thread,interrupted() //Determine whether it is interrupted, and clear the current interrupt status

The thread uses the method isInterrupted() to determine whether it is interrupted, or it can call the static method Thread.interrupted() to determine whether the current thread is interrupted, but Thread.interrupted() will also rewrite the interrupt flag to false.

The isInterrupted() method is of boolean type, if the thread is interrupted, it returns true, otherwise it returns false

If a thread is in a blocking state (such as thread calling thread.sleep, thread.join, thread.wait, etc.), if the thread is checking the interrupt flag, if the interrupt flag is found to be true, it will be thrown at these blocking method calls An InterruptedException exception is thrown, and the interrupt flag bit of the thread will be cleared immediately after the exception is thrown, that is, reset to false.

It is not recommended to customize a cancel flag to stop the thread. Because there is a blocking call in the run method, the cancellation flag cannot be detected quickly, and the thread must return from the blocking call before checking the cancellation flag. In this case, it’s better to use interrupts because,

First, the general blocking method, such as sleep, supports interrupt checking.
Second, there is no difference between checking the status of the interrupt bit and checking the cancel flag. Using the status of the interrupt bit can also avoid declaring the cancel flag and reduce resource consumption.
Note: A thread in a deadlock state cannot be interrupted

Case interrupt method to interrupt the thread

Interrupt Thread thread

Interrupt the thread after one second.
Execute the main method to view the console print and the time stamp. You will find that the thread is interrupted after 1000 milliseconds (one second)


import utils.SleepTools;

public class UseThread extends Thread {
    
    
	public UseThread(String name) {
    
    
		super(name);
	}

	@Override
	public void run() {
    
    
		String threadName = Thread.currentThread().getName();
		while (!isInterrupted()) {
    
    //检查当前线程是否被中断(平时开发用这个就行了)

			System.out.print(threadName + " 正在运行    ,");
			System.out.println(threadName + "内部interrrupt标记 = "
					+ isInterrupted() + "当前系统时间戳是" + System.currentTimeMillis());

		}

		//建议在下面的输出语句打断点,更好的查看效果
		System.out.print("线程将要停止了,   ");
		System.out.println(threadName + " interrrupt标记 =" + isInterrupted()+ "  当前系统时间戳是" + System.currentTimeMillis() );//变成true就是中断了
	}

	public static void main(String[] args) {
    
    
		UseThread thread = new UseThread("线程1");
		thread.start();
		SleepTools.second(1);//睡眠一秒
		thread.interrupt();//中断线程,其实设置线程的标识位true

	}
}

Interrupt Runnable thread

Interrupt the thread after one second.
Execute the main method to view the console print and the time stamp. You will find that the thread is interrupted after 1000 milliseconds (one second)


import utils.SleepTools;

public class UseRunnable implements Runnable {
    
    
	@Override
	public void run() {
    
    
//		boolean interrupted = Thread.currentThread().isInterrupted(); 主要这么写,中断线程无效
//		while (!interrupted) {// 不要这么写,中断线程无效

		while (!Thread.currentThread().isInterrupted()) {
    
    
			System.out.println(Thread.currentThread().getName()
					+ "我是实现Runnable的线程,此时的interrupt标记位是 "
					+ Thread.currentThread().isInterrupted() + "当前系统时间戳是" + System.currentTimeMillis());
		}

		System.out.println(Thread.currentThread().getName() + "interrupt 标记 是" +
				Thread.currentThread().isInterrupted() + "当前系统时间戳是" + System.currentTimeMillis());
	}


	public static void main(String[] args) {
    
    
		UseRunnable useRunnable = new UseRunnable();
		Thread thread = new Thread(useRunnable, "Runnable线程");
		thread.start();

		SleepTools.second(1);//睡眠一秒

//		Thread.currentThread().interrupt(); 这样中断线程是无效的,不要这么写

		thread.interrupt(); //设置中断线程

	}
}


Abnormally interrupted thread

If you want to interrupt the thread if you want to send an exception, please use Thread.currentThread().interrupt() in the catch code block;
if you don't do this, certain consequences will occur. For the specific consequences, run the following code to see the effect.



import utils.SleepTools;

public class UseRunnable implements Runnable {
    
    
	@Override
	public void run() {
    
    
//		boolean interrupted = Thread.currentThread().isInterrupted(); 主要这么写,中断线程无效
//		while (!interrupted) {// 不要这么写,中断线程无效

		while (!Thread.currentThread().isInterrupted()) {
    
    
			try {
    
    

				System.out.println(Thread.currentThread().getName() + "我是实现Runnable的线程,此时的interrupt标记位是 " + Thread.currentThread().isInterrupted());
				int a = 1 / 0;
			} catch (Exception e) {
    
    
				/*需要在catch里面手动中断一下,如果想知道不这样写的后果,
				可以注释这个代码试试  , 然后仔细观察控制台打印输出语句.,*/
//				Thread.currentThread().interrupt();
				e.printStackTrace();
			}


		}

		System.out.println(Thread.currentThread().getName() + "interrupt 标记 是" +
				Thread.currentThread().isInterrupted());
	}


	public static void main(String[] args) {
    
    
		UseRunnable useRunnable = new UseRunnable();
		Thread thread = new Thread(useRunnable, "Runnable线程");
		thread.start();

		SleepTools.second(1);//睡眠一秒

//		Thread.currentThread().interrupt(); 这样中断线程是无效的,不要这么写

		thread.interrupt(); //设置中断线程

	}
}


Guess you like

Origin blog.csdn.net/qq_41489540/article/details/109109945