多线程-两阶段终止

124 阅读1分钟

两阶段终止模式

Two Phase Termination

在一个线程T1中如何优雅终止T2?这里的【优雅】指的是给T2一个料理后事的机会

错误思路

  • 使用线程对象的stop()方法停止线程

    stop方法会真正的杀死线程,会释放所持有的锁对象,造成数据不一致

  • 使用System.exit(int)方法停止线程

    目的仅是停止一个线程,但这种做法会让整个程序都停止

正确思路

方法-Interrupted打断标记判断

@Slf4j(topic = "c.TwoPhaseTermination")
class TwoPhaseTermination {
	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);//情况1
					log.debug("执行监控记录");
				} catch (InterruptedException e) {
					e.printStackTrace();
					Thread thread = Thread.currentThread();
					thread.interrupt();
				}
			}
		});
		monitor.start();
	}
	//停止监控线程
	public void stop(){
		monitor.interrupt();
	}
}

方法-volatile可见性标记

@Slf4j(topic = "c.Main")
public class Main {
	volatile static boolean flag = true;
	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread(() -> {
			while (true){
				//是否被打断
				if (flag){
					//没有打断正常运行
					int i = 0;
					i++;
				}else {
					//料理后事
					log.debug("线程将要退出");
					break;
				}
			}
		});
		t1.start();
		Thread.sleep(1000);
		flag = false;
		t1.join();
		log.debug("主线程结束");
	}
}