多线程-Thread类的常用方法及使用场景

众所周知,操作线程就必须熟读线程的API方法,万一你开个多线程刹不住车就歇菜了,下面就介绍一些API基本用法。包括sleep,join,yield,interrupt。

sleep,让当前线程睡一会。原生用法Thread.sleep(毫秒),会抛出一个打断的异常;此方法可防止CPU100%的问题,如果你代码中有轮训机制,就会体验到。while(true) 中加上一个sleep,CPU至少会减低80%消耗。一般我们采用自制工具类。因为JUC中支持改玩意,不需要每次去catch异常

public class SleepUtils {
    public static void sleep(int second){
        try {
            TimeUnit.SECONDS.sleep(second);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

join是等待调用join线程结束继续运行,一般用于线程间通信。比如t1烧水,t2泡茶两个线程。显然t2需要等t1结束后才能开始,那么就可以使用t1.join()来实现。

join代码展示

@Slf4j
public class Thread03 {
    public static int i =0;
    public static void main(String[] args) throws Exception{
       Thread t1 =  new Thread(()->{
            log.info("t1 start");
            SleepUtils.sleep(1);
            i++;
        });
        t1.start();
        t1.join();//必须等t1执行完,否则可能i=0
        log.info("t1 start i={}",i);
    }
}

yield是指短暂放弃CPU使用权,让其他线程优先执行。这个在处理冷热数据的时候可用上。如t1,t2两个线程都是处理售票,t2可能封面搞了个美女访问量更多,但其实t1,t2两个是同时抢占CPU时间片在运行的,在java层面就可以t1线程使用Thread.yield() 让t2单位时间处理能力更强。

interrupt是打断线程。这里分两种情况,当打断打断运行线程时不会中断服务,会继续执行打断后逻辑,打断后标记为true。当打断阻塞线程 sleep wait join 会中断服务,打断后打断标记仍为false。

interrupt代码展示,这个例子就是线程二阶段打断,判断了运行时打断和阻塞时打断。以及打断标识的处理。

@Slf4j
public class ThreadInterrupt02 {
    public static void main(String[] args) {
        /**
         * 有一个监控线程,如果出现异常则停止,如果未出现继续监控
         */
        Monitor monitor = new Monitor();
        monitor.start();
        SleepUtils.sleep(5);//休眠5s后执行打断操作
        monitor.stop();
    }
}

@Slf4j
    class Monitor {
        private Thread monitor;

        public void start(){
            monitor = new Thread(()->{
                while (true){
                    log.info("monitor 正在监控中");
                    //判断当前线程上次是否被打断,如果打断直接退出
                   if (Thread.currentThread().isInterrupted()) {
                       log.info("monitor 被打断");
                       break;
                   }
                   //如果没退出,休眠2秒继续执行,此过程可能会打断
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        log.info("睡眠被打断");
                        e.printStackTrace();
                        Thread.currentThread().interrupt();//如果在睡眠过程被打断,标识仍为false,不会break,所以这里二次打断
                    }
                }
            });
            monitor.start();
        }
        public void stop(){
            monitor.interrupt();
            log.info("线程执行打断");
        }
    }

扫描二维码关注公众号,回复: 15817059 查看本文章

猜你喜欢

转载自blog.csdn.net/weixin_42740540/article/details/124124764