保证多线程顺序执行,四种方案,你知道几种?

2023年 8月 28日 104.1k 0

故事

上周一位同学在面试中遇到了这么一道问题:

有三个线程T1、T2、T3,如何保证顺序执行?

常规操作,启动三个线程,让其执行。

public class ThreadDemo {
public static void main(String[] args) {

final Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程1");
}
});

final Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程2");
}
});

Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程3");
}
});
t1.start();
t2.start();
t3.start();
}
}

登录后复制

运行结果:

线程2
线程1
线程3

登录后复制

调用三个线程的start方法,很明显是按照顺序调用的,但是每次运行出来的结果,基本上都不相同,随机性特别强。

怎么办呢?下面我们使用四种方案来实现。

方案一

我们可以利用Thread中的join方法解决线程顺序问题,下面我们来简单介绍一下join方法。

官方介绍:

Waits for this thread to die.

等待这个线程结束,也就是说当前线程等待这个线程结束后再继续执行 。

join()方法是Thread中的一个public方法,它有几个重载版本:

  • join()
  • join(long millis) //参数为毫秒
  • join(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒

join()方法实际是利用了wait()方法(wait方法是Object中的),只不过它不用等待notify()/notifyAll(),且不受其影响。

它结束的条件是:

  • 等待时间到
  • 目标线程已经run完(通过isAlive()方法来判断)

下面大致看看器源码:

public final void join() throws InterruptedException {
//调用了另外一个有参数的join方法
join(0);
}
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis t2.start())
.thenRun(()->t3.start());
}

static class Work implements Runnable{
@Override
public void run() {
System.out.println("执行 : " + Thread.currentThread().getName());
}
}
}

登录后复制

运行结果:

执行 : 线程1
执行 : 线程2
执行 : 线程3

登录后复制

到此,我们就使用CompletableFuture实现了多个线程顺序执行的问题。

总结

关于多个线程顺序执行,不管是对于面试,还是工作,关于多线程顺序执行的解决方案都是非常有必要掌握的。:

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论