一 体系化深入学习并发编程由简入繁系统梳理并发知识点( 八 )

public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(()->{for (int i = 0; i <10; i++) {System.out.println(i);try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();break;}}});thread.start();TimeUnit.SECONDS.sleep(5);thread.interrupt();}
因为sleep方法只能接受毫秒为单位的参数,当休眠时间过长的时候,还需要人为区计算,比较繁琐;而提供了更多基本时间单位作为参数传入,更加简单明了.sleep方法中,判断了参数小于0的情况,如果传入参数小于0,则抛出异常;而的sleep中,如果参数小于0,则不休眠,不会影响程序的正常运行
通常使用sleep方法的地方,都可以用该方法来代替
public void sleep(long timeout) throws InterruptedException {if (timeout > 0) {long ms = toMillis(timeout);int ns = excessNanos(timeout, ms);Thread.sleep(ms, ns);}}
.join()
简洁明了:
Waits for thisto die.
调用这个方法的线程,需要等待子线程结束,才能继续运行
public static void main(String[] args) throws InterruptedException {Long before = System.currentTimeMillis();Thread thread =new Thread(()->{System.out.println(Thread.currentThread().getName()+"开始运行");try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"结束运行");});thread.start();thread.join();Long after = System.currentTimeMillis();System.out.println("主线程执行完毕"+(after-before));}
该方法执行结果:
Thread-0开始运行Thread-0结束运行主线程执行完毕5099
而如果把join这行代码注释掉,再运行,则变成了主线程先执行完,子线程可能还没启动或者还在休眠 。
主线程执行完毕94Thread-0开始运行Thread-0结束运行
join响应中断
join方法响应中断的对象不同,因为之前调用wait、sleep方法的都是子线程,所以响应中断的线程是子线程
而调用join方法的是主线程,所以要主线程来响应中断
public static void main(String[] args){//获取主线程Thread main = Thread.currentThread();Thread thread = new Thread(()->{System.out.println(Thread.currentThread().getName()+"开始运行");try {//在子线程中中断主线程main.interrupt();TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {System.out.println(Thread.currentThread().getName()+"被中断了");}});thread.start();try {thread.join();} catch (InterruptedException e) {System.out.println(Thread.currentThread().getName()+"被中断了");}System.out.println("主线程结束运行");
通过子线程来打断主线程
Thread-0开始运行main被中断了主线程结束运行
不过有个问题是,主线程已经结束了,但是子线程并没有收到打断干扰,所以仍然还在运行,所以应该在主线程捕获到异常时,对子线程进行打断
catch (InterruptedException e) {thread.interrupt();System.out.println(Thread.currentThread().getName()+"被中断了");}
join时主线程的状态
查看主线程在执行join语句时,是什么状态
public static void main(String[] args) throws InterruptedException {Thread main = Thread.currentThread();Thread thread = new Thread(()->{try {TimeUnit.SECONDS.sleep(5);//打印join时主线程的状态System.out.println("join期间主线程状态:"+main.getState());} catch (InterruptedException e) {e.printStackTrace();}});thread.start();System.out.println("join前主线程状态:"+main.getState());thread.join();System.out.println("join后主线程状态:"+main.getState());