1.背景
在实际开发中,我们可能会遇到终端某个线程的场景,
比如不断扫描数据库的发货订单时,这时候需停止扫描,
当然我们不能把程序关了,我们只希望停止扫描数据库这一个线程,
那么应该怎么办了?
这就可以使用线程中提供的interrupt()这个方法
2.案例演示
package com.ldp.demo01; import com.common.MyThreadUtil; import lombok.extern.slf4j.Slf4j; import org.junit.Test; /** * @author 姿势帝-博客园 * @address https://www.cnblogs.com/newAndHui/ * @WeChat 851298348 * @create 01/16 9:41 * @description <p> * interrupt()方法的理解 * 1.只是给线程设置一个打断标记,不会改变线程的实际状态 * 2.打断睡眠中的线程会清除打断标记(即标记无效) * 3.实际应用中可以利用判断线程的打断标记,来判断是否继续业务. * </p> */ @Slf4j public class Test03Interrupt { /** * 打断正常的线程 * 1. t1.interrupt() 只是给线程设置一个打断标记,不会改变线程的实际状态 */ @Test public void test01() { Thread t1 = new Thread(() -> { log.info("执行中......"); while (true) { } }, "t1"); // 启动线程 t1.start(); // 查看打断状态 log.info("interrupted=" + t1.isInterrupted()); // 查看线程状态 log.info("线程状态为:" + t1.getState()); // 睡眠2秒 MyThreadUtil.sleep(2); // 打断线程 t1.interrupt(); // 查看打断状态 log.info("interrupted=" + t1.isInterrupted()); // 再次查看线程状态 log.info("线程状态为:" + t1.getState()); // 防止主线程结束 MyThreadUtil.sleep(10); } /** * 打断处于睡眠的线程 * 1. 打断睡眠中的线程会清除打断标记(即标记无效) */ @Test public void test02() { Thread t1 = new Thread(() -> { while (true) { log.info("执行中......"); Thread currentThread = Thread.currentThread(); if (currentThread.isInterrupted()) { log.info("isInterrupted=true"); break; } try { Thread.sleep(50 * 1000); } catch (InterruptedException e) { e.printStackTrace(); log.info("isInterrupted=" + currentThread.isInterrupted()); // 重新设置打断标记 currentThread.interrupt(); } } }, "t1"); // 启动线程 t1.start(); // 睡眠2秒 MyThreadUtil.sleep(2); // 打断线程 t1.interrupt(); // 查看打断状态 log.info("isInterrupted=>" + t1.isInterrupted()); // 防止主线程结束 MyThreadUtil.sleep(10); } /** * 两阶段终止 * 案例: * 假设有一个主线程一直在扫描数据的订单进行发货操作, * 在页面有我们需要有暂停发货\继续发货\停止发货三个功能 */ @Test public void test03() { // 扫描数据线程 Thread threadDataMain = new Thread(() -> { Thread currentThread = Thread.currentThread(); while (true) { boolean interrupted = currentThread.isInterrupted(); if (interrupted) { // 如果线程被打断就停止循环 log.info("停止获取数据"); break; } // 模拟读取数据数据,每次1条 String order = getOrder(); if (order == null) { log.info("无数据休息2秒"); // 数据库无订单休息2秒 try { Thread.sleep(2 * 1000); } catch (InterruptedException e) { e.printStackTrace(); // 重新设置打断标记 currentThread.interrupt(); } continue; } // 发货线程 Thread threadOrder = new Thread(() -> { log.info("订单发货中:" + order); }, "t-" + order); threadOrder.start(); } }, "thread-数据库扫描主线程"); threadDataMain.start(); // 模拟发货10秒后停止发货 MyThreadUtil.sleep(10); threadDataMain.interrupt(); // 防止主线程结束 MyThreadUtil.sleep(20); } /** * 模拟数据库获取订单 * * @return */ public String getOrder() { // 模拟有时候无数据的情况 // int nextInt = new Random().nextInt(10); long millis = System.currentTimeMillis(); if (millis % 3 > 0) { return null; } // 3的整数倍才返回订单 return "NO" + System.currentTimeMillis(); } }