如何确保三个线程顺序执行x
时间:2020-09-21 13:37:02 来源:雅意学习网 本文已影响 人
如何确保三个线程顺序执行
场景:有三个线程 t1、t2、t3。确保三个线程 t1 执行完后 t2 执行,t2 执行完成后 t3 执行。
1、thread.Join 把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程 B 中调用了线程 A 的 Join()方法,直到线程 A 执行完毕后,才会继续执行线程 B 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public
class
ThreadTest1 {
// T1、T2、T3 三个线程顺序执行
public
static
void
main(String[] args) {
Thread t1 = new
Thread(new
Work(null));
Thread t2 = new
Thread(new
Work(t1));
Thread t3 = new
Thread(new
Work(t2));
t1.start();
t2.start();
t3.start();
}
static
class
Work implements
Runnable {
private
Thread beforeThread;
public
Work(Thread beforeThread) {
this.beforeThread = beforeThread;
}
public
void
run() {
if
(beforeThread != null) {
try
{
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
beforeThread.join();
System.out.println("thread start:"
+ Thread.currentThread().getName());
} catch
(InterruptedException e) {
e.printStackTrace();
}
} else
{
System.out.println("thread start:"
+ Thread.currentThread().getName());
}
}
}
}
2、使用 CountDownLatch CountDownLatch(闭锁)是一个很有用的工具类,利用它我们可以拦截一个或多个线程使其在某个条件成熟后再执行。它的内部提供了一个计数器,在构造闭锁时必
须指定计数器的初始值,且计数器的初始值必须大于 0。另外它还提供了一个countDown 方法来操作计数器的值,每调用一次 countDown 方法计数器都会减 1,直到计数器的值减为 0 时就代表条件已成熟,所有因调用 await 方法而阻塞的线程都会被唤醒。这就是 CountDownLatch 的内部机制,看起来很简单,无非就是阻塞一部分线程让其在达到某个条件之后再执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public
class
ThreadTest2 {
// T1、T2、T3 三个线程顺序执行
public
static
void
main(String[] args) {
CountDownLatch c0 = new
CountDownLatch(0); //计数器为 0
CountDownLatch c1 = new
CountDownLatch(1); //计数器为 1
CountDownLatch c2 = new
CountDownLatch(1); //计数器为 1
Thread t1 = new
Thread(new
Work(c0, c1));
//c0 为 0,t1 可以执行。t1 的计数器减 1
Thread t2 = new
Thread(new
Work(c1, c2));
//t1 的计数器为 0 时,t2 才能执行。t2 的计数器 c2 减 1
Thread t3 = new
Thread(new
Work(c2, c2));
//t2 的计数器 c2 为 0 时,t3 才能执行
t1.start();
t2.start();
t3.start();
}
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 3//定义 Work 线程类,需要传入开始和结束的 CountDownLatch 参数
static
class
Work implements
Runnable {
CountDownLatch c1;
CountDownLatch c2;
Work(CountDownLatch c1, CountDownLatch c2) {
super();
this.c1 = c1;
this.c2 = c2;
}
public
void
run() {
try
{
c1.await();//前一线程为 0 才可以执行
System.out.println("thread start:"
+ Thread.currentThread().getName());
c2.countDown();//本线程计数器减少
} catch
(InterruptedException e) {
}
}
}
}
5 36 37 38 39 40 41 42 43 44 45