两阶段终止模式
两阶段终止模式
在并发时,如何让一个线程T1优雅地终止线程T2,优雅指的是给T2一个料理后事的机会。
方法1——利用interrupt

@Slf4j(topic = "c.two")
public class MyTwoInterrupt_ByInterrupt {
    public static void main(String[] args) throws InterruptedException {
        TwoInterruptTermination termination = new TwoInterruptTermination();
        termination.start();
        Thread.sleep(3500);
        termination.stop();
    }
}
@Slf4j(topic = "c.two")
class TwoInterruptTermination {
    private Thread thread;
    public void start() {
        thread = new Thread(() -> {
            while (true) {
                log.debug("执行监控");
                Thread currentThread = Thread.currentThread();
                if (currentThread.isInterrupted()) {
                    log.debug("料理后事");
                    break;
                } else {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        currentThread.interrupt();    //让程序有料理后事的过程,优雅
                    }
                }
            }
        });
        thread.start();
    }
    public void stop() {
        thread.interrupt();
    }
}
方法2——park配合inturrupt
- park配合inturrupt使用,优雅的暂停、继续线程
- park只能打断一次:park进程通过inturrupt继续运行之后,打断标志为true,无法继续打断
- 通过interrupted方法设置打断标志为false,才能继续调用park方法,打断
| 方法 | 作用域 | 作用 | 
|---|---|---|
| interrupted() | static | 判断当前线程是否被打断,清除打断标记——设置打断标记为false | 
| park() | LockSupport | 线程暂停,让出cpu | 
| interrupt() | 非static | 打断线程 | 
private static void main(String[] args) throws Exception{
    Thread t = new Thread(()->{
        log.debug("暂停之前");
        LockSupport.park();
        log.debug("打断状态:{}", Thread.isInterrupt());
    });
    
    t.start();
    
    try {Thread.sleep(1000);} catch(Exception e) {}
    t.interrupt();
}
运行结果:
暂停之前
(等待一秒)
打断状态:true
问题:如果打断标记已经是 true, 再次 park 会失效
解决方法:可以使用 Thread.interrupted() 清除打断状态
private static void main(String[] args) throws Exception{
    Thread t = new Thread(()->{
        for(int i=0; i<4; i++) {
            log.debug("parking");
        	LockSupport.park();
        	+log.debug("打断状态:{}", Thread.interrupted());
        }
    });
    
    t.start();
    
    try {Thread.sleep(1000);} catch(Exception e) {}
    t.interrupt();
}
结果:
暂停之前
打断状态:true
    
暂停之前
打断状态:true
    
暂停之前
打断状态:true
    
暂停之前
打断状态:true

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号