多线程顺序运行的 4 种方法,面试随便问!
沈阳市和平区爱尚职业培训机构
发表于:2022-07-22 16:44:16 17次浏览文章介绍4种方法,简单易懂,通过4个demo抛砖引玉。
1、在子线程中通过join()方法顺序
通过join()
方法使当前线程“阻塞”,等待线程执行完毕后继续执行。
“举例:在线程thread2中,加上一句thread1.join(),其意义在于,当前线程2运行到此行代码时会进入阻塞状态,直到线程thread1执行完毕后,线程thread2才会继续运行,这就保证了线程thread1与线程thread2的运行顺序。
”
public class ThreadJoinDemo { public static void main(String[] args) throws InterruptedException { final Thread thread1 = new Thread(new Runnable() { @Override public void run() { System.out.println("打开冰箱!"); } }); final Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { thread1.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("拿出一瓶牛奶!"); } }); final Thread thread3 = new Thread(new Runnable() { @Override public void run() { try { thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("关上冰箱!"); } }); //下面三行代码顺序可随意调整,程序运行结果不受影响,因为我们在子线程中通过“join()方法”已经了运行顺序。 thread3.start(); thread2.start(); thread1.start(); } }
运行结果:
打开冰箱! 拿出一瓶牛奶! 关上冰箱!
2、在主线程中通过join()方法顺序
简单说一下子线程与主线程的区别,子线程指的是发生在Thread内部的代码,主线程指的是发生在main函数中的代码。
我们可以在main函数中通过join()
方法让主线程阻塞等待以达到顺序执行的目的。
public class ThreadMainJoinDemo { public static void main(String[] args) throws InterruptedException { final Thread thread1 = new Thread(new Runnable() { @Override public void run() { System.out.println("打开冰箱!"); } }); final Thread thread2 = new Thread(new Runnable() { @Override public void run() { System.out.println("拿出一瓶牛奶!"); } }); final Thread thread3 = new Thread(new Runnable() { @Override public void run() { System.out.println("关上冰箱!"); } }); thread1.start(); thread1.join(); thread2.start(); thread2.join(); thread3.start(); } }
输出结果:
打开冰箱! 拿出一瓶牛奶! 关上冰箱!
3、通过倒数计时器CountDownLatch实现
CountDownLatch通过计数器提供了更灵活的控制,只要检测到计数器为0当前线程就可以往下执行而不用管相应的thread是否执行完毕。
public class ThreadCountDownLatchDemo { private static CountDownLatch countDownLatch1 = new CountDownLatch(1); private static CountDownLatch countDownLatch2 = new CountDownLatch(1); public static void main(String[] args) { final Thread thread1 = new Thread(new Runnable() { @Override public void run() { System.out.println("打开冰箱!"); countDownLatch1.countDown(); } }); final Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { countDownLatch1.await(); System.out.println("拿出一瓶牛奶!"); countDownLatch2.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }); final Thread thread3 = new Thread(new Runnable() { @Override public void run() { try { countDownLatch2.await(); System.out.println("关上冰箱!"); } catch (InterruptedException e) { e.printStackTrace(); } } }); //下面三行代码顺序可随意调整,程序运行结果不受影响 thread3.start(); thread1.start(); thread2.start(); } }
输出结果:
打开冰箱! 拿出一瓶牛奶! 关上冰箱!
4、通过创建单一化线程池newSingleThreadExecutor()实现
单线程化线程池(newSingleThreadExecutor)的优点,串行执行所有任务。
public class ThreadPoolDemo { static ExecutorService executorService = Executors.newSingleThreadExecutor(); public static void main(String[] args) { final Thread thread1 = new Thread(new Runnable() { @Override public void run() { System.out.println("打开冰箱!"); } }); final Thread thread2 =new Thread(new Runnable() { @Override public void run() { System.out.println("拿出一瓶牛奶!"); } }); final Thread thread3 = new Thread(new Runnable() { @Override public void run() { System.out.println("关上冰箱!"); } }); executorService.submit(thread1); executorService.submit(thread2); executorService.submit(thread3); executorService.shutdown(); //使用完毕记得关闭线程池 } }
输出结果:
打开冰箱! 拿出一瓶牛奶! 关上冰箱!
沈阳爱尚实训开设JAVA,前端,UED,Python、大数据、新媒体等课程。5-10人小班教学,90天全程面授、课程每年同步名企需求、大厂项目案例、双五导师(5年以上名企+培训经验)授课、全流程团队开发、闯关式教育、双平台(OTO)巩固学习、就业薪水高,毕业一周内名企录取通知任您选、一次交费学会为止、老学员训练营助力职场技能提升、终身跳槽服务,详情可查看“沈阳爱尚实训”。
多线程顺序运行的 4 种方法,面试随便问!原创内容,请点击 沈阳JAVA培训
热门课程
-
沈阳java架构师培训课程
询价
-
沈阳Java零基础5-10人就业班
询价
-
沈阳java架构课程零基础培训班
询价
-
Java零基础从入门到精通
询价
-
沈阳java零基础就业班
询价