并发编程-两阶段终止模式

1.1 sleep 与 yield

sleep

  1. 调用 sleep 会让当前线程从 Running 进入 Timed Waiting 状态(阻塞)
  2. 其它线程可以使用 interrupt 方法打断正在睡眠的线程,这时 sleep 方法会抛出 InterruptedException
  3. 睡眠结束后的线程未必会立刻得到执行
  4. 建议用 TimeUnit 的 sleep 代替 Thread 的 sleep 来获得更好的可读性

yield

  1. 调用 yield 会让当前线程从 Running 进入 Runnable 就绪状态,然后调度执行其它线程
  2. 具体的实现依赖于操作系统的任务调度器

1.2 线程优先级

  • 线程优先级会提示(hint)调度器优先调度该线程,但它仅仅是一个提示,调度器可以忽略它
  • 如果 cpu 比较忙,那么优先级高的线程会获得更多的时间片,但 cpu 闲时,优先级几乎没作用

1.2 join 方法

  • 需要等待结果返回,才能继续运行就是同步

  • 不需要等待结果返回,就能继续运行就是异步

     		join()  等待线程运行结束
     		join(long n)  等待线程运行结束,最多等待 n 毫秒
    

join方法执行后会等待调用join方法的线程执行完,才会继续执行下面的代码

1.3 interrupt 方法

  1. 打断 sleep,wait,join 的线程
  2. 这几个方法都会让线程进入阻塞状态
  3. 打断 sleep 的线程, 会清空打断状态

打断正常运行的线程

  • 打断正常运行的线程, 不会清空打断状态
  • interrupt 可以打断正在执行的线程,无论这个线程是在 sleep,wait,还是正常运行

1.2 两阶段终止模式

Two Phase Termination

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

在这里插入图片描述
代码如下

@Slf4j(topic = "c.test1")
public class test1 {
    public static void main(String[] args) throws InterruptedException {
        TwoPhaseTermination tpt = new TwoPhaseTermination();
        tpt.start();

        Thread.sleep(3500);
        tpt.stop();

    }

    @Slf4j(topic = "c.TwoPhaseTermination")
    static 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);
                        log.debug("执行监控任务");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        //sleep出现异常后,会重置打断标记
                        //需要重置打断标记
                        current.interrupt();
                    }
                }
            });
            monitor.start();
        }

        public void stop(){
            monitor.interrupt();
        }
    }
}

sleep被打断后会出现异常,会清除打断标记,会返回默认的false

所以需要再调用interrupt方法重置打断标记,返回true

  • isInterrupted() 判断是否被打断, 不会清除 打断标记
  • interrupted() static 判断当前线程是否被打断 会清除 打断标记

注意:使用logback日志@Slf4j IDEA需要安装Lombok插件

  • IDEA安装Lombok插件失败的解决方案
  • 参考 https://www.cnblogs.com/han-1034683568/p/9134980.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值