进入网络管理的网站,泰安市最新消息今天,苏州优化排名seo,如何做网站店铺前几天有一位同事在阿里一面的时候被问到这么一个多线程问题#xff1a;如何保证多个线程的顺序执行。当时他没有回答上来#xff0c;所以为了避免大家以后遇到同样的面试题还是回答不上来#xff0c;今天我们就来分析解答下这个问题。问题缘由由于线程执行是靠CPU分时间片来…前几天有一位同事在阿里一面的时候被问到这么一个多线程问题如何保证多个线程的顺序执行。当时他没有回答上来所以为了避免大家以后遇到同样的面试题还是回答不上来今天我们就来分析解答下这个问题。问题缘由由于线程执行是靠CPU分时间片来处理的那么多个线程执行的时候如果不加限制那么线程的执行顺序是无法保证的。如下源码public class OrderThreadMain { public static void main(String[] args) { Thread A new Thread(()-{ System.out.println(A); }); Thread B new Thread(()-{ System.out.println(B); }); Thread C new Thread(()-{ System.out.println(C); }); A.start(); B.start(); C.start(); }}A B C三个线程同时启动最后的执行结果不是每次都顺序输出 A B C而是每次运行结果都是不一样的。有可能输出A B C有也可能输出 B A C是无法保证线程的顺序执行的。join方式实现join方式即使用Thread.join方法来实现。Thread.join含义当前线程需要等待previousThread线程终止之后才从thread.join返回。简单来说就是线程没有执行完之前会一直阻塞在join方法处。join方式实现方式存在两种主线程join和执行线程join。下面我们依次来分析一下1.主线程joinpublic class OrderThreadMain { public static void main(String[] args) throws InterruptedException { Thread A new Thread(()-{ System.out.println(A); }); Thread B new Thread(()-{ System.out.println(B); }); Thread C new Thread(()-{ System.out.println(C); }); A.start(); //等待A线程执行完在启动B线程 A.join(); B.start(); //等待B线程执行完在启动C线程 B.join(); C.start(); C.join(); }}//输出结果://A //B//C上面源码就是主线程join的实现方式其原理就是保证执行线程执行完毕再start后续线程从而实现多个线程的顺序执行。2.执行线程joinpackage com.example.demo.concurrent;import java.util.concurrent.Executors;public class OrderThreadMain { static class TestThread extends Thread{ private Thread beforeThread; private String str; TestThread(Thread beforeThread, String str){ this.beforeThread beforeThread; this.str str; } Override public void run() { if (beforeThread ! null){ try { beforeThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(str); } } public static void main(String[] args) { TestThread A new TestThread(null, A); TestThread B new TestThread(A, B); TestThread C new TestThread(B, C); A.start(); B.start(); C.start(); }}//输出结果://A //B//C上面源码就是执行线程join的实现方式其原理就是通过传入beforeThread(在这个线程执行前需要执行完的线程对象)来保证多个线程顺序执行。Thread.join源码实现public final void join() throws InterruptedException { join(0);}public final synchronized void join(long millis) throws InterruptedException { long base System.currentTimeMillis(); long now 0; if (millis 0) { throw new IllegalArgumentException(timeout value is negative); } if (millis 0) { //一直轮训线程是否执行完毕执行完毕则结束执行未完毕一直轮训 while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay millis - now; if (delay 0) { break; } wait(delay); now System.currentTimeMillis() - base; } } }由Thread.join源码可以知道Thread.join原理其实很简单就是如果线程还未执行完成就一直轮训等待执行完成则结束轮训继续执行后续代码。Executors.newSingleThreadExecutor方式实现Executors.newSingleThreadExecutor是一种特殊的线程池实现它是一个单线程的线程池核心线程数和最大线程数都为1相当于串行执行所以可以通过它来实现多个线程顺序执行。注如果大家对线程池不是很了解可以阅读作者之前一篇关于线程池的文章阿里P8大佬总结Java线程池详解看了你就懂public class OrderThreadMain { public static void main(String[] args) { Runnable A new Runnable() { Override public void run() { System.out.println(A); } }; Runnable B new Runnable() { Override public void run() { System.out.println(B); } }; Runnable C new Runnable() { Override public void run() { System.out.println(C); } }; ExecutorService executorService Executors.newSingleThreadExecutor(); //按顺序提交任务 可以保证多个线程按提交顺序执行 executorService.submit(A); executorService.submit(B); executorService.submit(C); }}//输出结果://A //B//C上面源码就是Executors.newSingleThreadExecutor的实现方式只要保证任务时按顺序提交那么就能保证多个线程任务的顺序执行。END笔者是一位热爱互联网、热爱互联网技术、热于分享的年轻人如果您跟我一样我愿意成为您的朋友分享每一个有价值的知识给您。喜欢作者的同学点赞转发关注哦点赞转发关注私信作者“读书笔记”即可获得BAT大厂面试资料、高级架构师VIP视频课程等高质量技术资料。BAT等一线互联网面试资料和VIP高级架构师视频