多线程顺序运行的 4 种方法,面试随便问!
Posted Java技术栈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程顺序运行的 4 种方法,面试随便问!相关的知识,希望对你有一定的参考价值。
文章介绍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();
基础就不介绍了,多线程系列我博客教程写了很多了,这里推荐大家看看吧:https://www.javastack.cn/categories/Java/
输出结果:
打开冰箱!
拿出一瓶牛奶!
关上冰箱!
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(); //使用完毕记得关闭线程池
输出结果:
打开冰箱!
拿出一瓶牛奶!
关上冰箱!
来源:blog.csdn.net/jqc874789596/article/details/100557300
近期热文推荐:
1.1,000+ 道 Java面试题及答案整理(2022最新版)
4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!
觉得不错,别忘了随手点赞+转发哦!
以上是关于多线程顺序运行的 4 种方法,面试随便问!的主要内容,如果未能解决你的问题,请参考以下文章