h5页面 个人网站/网站地址ip域名查询
目录
- 一、简述
- 二、用两阶段终止模式终止监控操作
- 1.利用 interrupted
- 2.利用停止标记
一、简述
Two Phase Termination:简单来说就是将终止过程分成两个阶段,其中第一个阶段主要是线程 T1 向线程 T2发送终止指令,而第二阶段则是线程 T2响应终止指令(在这之前先进行处理操作。例如:释放锁,释放资源等)。而不是使用线程对象的 stop() 方法强制停止线程。
二、用两阶段终止模式终止监控操作
实际工作中,需要有监控系统(监控线程)动态的检测被监控系统。监控系统发送采集指令从被监控系统收集数据。出于对性能的考虑,动态采集功能一般都会有终止操作。
下面通过interrupt() 方法和线程终止的标志位
模拟监控线程的终止操作。
1.利用 interrupted
@Slf4j(topic = "c.MonitorTest ")
class MonitorTest {private Thread monitor;public void start(){monitor = new Thread(() -> {while(true) {Thread current = Thread.currentThread();if(current.isInterrupted()) {log.debug("料理后事(释放资源等操作)");break;}try {Thread.sleep(1000);log.debug("接受数据");} catch (InterruptedException e) {//在外部进行了监控线程终止操作后,即stop//监控线程再次进入while循环后isInterrupted会返回true,最后退出循环结束线程//当外部进行终止操作时,监控线程可能执行到sleep,这时执行interrupt会发生异常,并清除打断标记//所以在catch块中要重新打断设置打断标记log.debug("重新打断");current.interrupt();}// 执行监控操作}},"监控线程");monitor.start();}public void stop() {monitor.interrupt();}
}
public static void main(String[] args) throws Exception{MonitorTest monitorTest=new MonitorTest();monitorTest.start();Thread.sleep(2500);log.debug("执行监控线程终止操作");monitorTest.stop();}
11:31:32.529 [监控线程] DEBUG c.MonitorTest - 接受数据
11:31:33.532 [监控线程] DEBUG c.MonitorTest - 接受数据
11:31:34.026 [main] DEBUG c.Test - 执行监控线程终止操作
11:31:34.026 [监控线程] DEBUG c.MonitorTest - 重新打断
11:31:34.026 [监控线程] DEBUG c.MonitorTest - 料理后事(释放资源等操作)
2.利用停止标记
@Slf4j(topic = "c.MonitorTest2")
class MonitorTest2 {private Thread monitor;//使用停止标记,避免了在catch块中的操作//停止标记用 volatile 是为了保证该变量在多个线程之间的可见性//外部线程调用stop方法修改stop为true后,对监控线程保持可见private volatile boolean stop = false;public void start(){monitor = new Thread(() -> {while(true) {Thread current = Thread.currentThread();if(stop) {log.debug("料理后事(释放资源等操作)");break;}try {Thread.sleep(1000);log.debug(接受数据");} catch (InterruptedException e) {}// 执行监控操作}},"监控线程");monitor.start();}public void stop() {stop = true;monitor.interrupt();}
}
public static void main(String[] args) throws Exception{MonitorTest2 monitorTest2=new MonitorTest2();monitorTest2.start();Thread.sleep(2500);log.debug("执行监控线程终止操作");monitorTest2.stop();}
11:35:21.838 [监控线程] DEBUG c.MonitorTest2 - 接受数据
11:35:22.842 [监控线程] DEBUG c.MonitorTest2 - 接受数据
11:35:23.337 [main] DEBUG c.Test - 执行监控线程终止操作
11:35:23.337 [监控线程] DEBUG c.MonitorTest2 - 料理后事(释放资源等操作)