六、线程中断机制
一、什么是中断?
首先,
一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。所以,Thread.stop、Thread.suspend、Thread.resume都已经被废弃了。
其次,
在Java中没有办法立即停止一条线程,然而停止线程却显得尤为重要,如取消一个耗时操作。
因此,Java提供了一种用于停止线程的机制——中断。
中断只是一种协作机制,Java没有给中断增加任何语法,中断的过程完全需要程序员自己实现。
若要中断一个线程,你需要手动调用该线程的interrupt方法,该方法也仅仅是将线程对象的中断标识设成true;
接着你需要自己写代码不断地检测当前线程的标识位,如果为true,表示别的线程要求这条线程中断,此时究竞该做什么需要你自己写代码实现。
每个线程对象中都有一个标识,用于表示线程是否被中断,该标识位为true表示中断,为false表示未中断;
通过调用线程对象的interrupt方法将该线程的标识位设为true;可以在别的线程中调用,也可以在自己的线程中调用。
二、相关API
1、public void interrupt()
仅仅是设置线程的中断状态为true,不会停止线程。
2、public static boolean interrupted()
判断线程是否被中断,并清除当前中断状态。这个方法做了两件事:
1返回当前线程的中断状态。
2将当前线程的中断状态设为false。
3、public boolean isInterrupted()
判断当前线程是否被中断〈通过检查中断标志位)。
三、如何中断?
1、通过volatile变量
public class test04 { static volatile boolean isStop = false; public static void main(String[] args) { new Thread(() -> { while (true) { if (isStop) { System.out.println("----- isStop =true,程序结束"); break; } System.out.println("-------------- hello isStop"); } }, "t1").start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { isStop = true; }, "t2").start(); } }
2、通过AtomicBoolean
public class test04 { static AtomicBoolean atomicBoolean = new AtomicBoolean(false); public static void main(String[] args) { new Thread(() -> { while (true) { if (atomicBoolean.get()) { System.out.println("----- atomicBoolean.get() =true,程序结束"); break; } System.out.println("-------------- hello isStop"); } }, "t1").start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { atomicBoolean.set(true); }, "t2").start(); } }
3、通过Thread类自带的中断api方法
public class test04 {public static void main(String[] args) { Thread t1 = new Thread(() -> { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("----- isInterrupted() =true,程序结束"); break; } System.out.println("-------------- hello isStop"); } }, "t1"); t1.start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { t1.interrupt(); }, "t2").start(); } }