- 通过倒数计时器CountDownLatch实现。
CountDownLatch通过计数器提供了更灵活的控制,只要检测到计数器为0当前线程就可以往下执行而不用管相应的thread是否执行完毕
private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
private static CountDownLatch countDownLatch3 = new CountDownLatch(1);
@Test
public void test1() throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "打开冰箱");
countDownLatch2.countDown();
}, "线程1");
Thread thread2 = new Thread(() -> {
try {
countDownLatch2.await();
System.out.println(Thread.currentThread().getName() + "拿出可乐" );
countDownLatch3.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "线程2");
Thread thread3 = new Thread(() -> {
try {
countDownLatch3.await();
System.out.println(Thread.currentThread().getName() + "关上冰箱" );
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "线程3");
thread3.start();
thread2.start();
thread1.start();
}
- 在主线程中通过join()方法指定顺序
通过join()方法使当前线程“阻塞”,等待指定线程执行完毕后继续执行。
在线程thread2中,加上一句thread1.join(),其意义在于,当前线程2运行到此行代码时会进入阻塞状态,直到线程thread1执行完毕后, 线程thread2才会继续运行,这就保证了线程thread1与线程thread2的运行顺序。
底层通过jdk synchronized wait notify 实现
@Test
public void test2() throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "打开冰箱");
}, "线程1");
Thread thread2 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "拿出可乐" );
}, "线程2");
Thread thread3 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "关上冰箱" );
}, "线程3");
thread1.start();
thread1.join();
thread2.start();
thread2.join();
thread3.start();
}
- 在子线程中通过join()方法指定顺序
@Test
public void test3() throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "打开冰箱");
}, "线程1");
Thread thread2 = new Thread(() -> {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "拿出可乐" );
}, "线程2");
Thread thread3 = new Thread(() -> {
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "关上冰箱" );
}, "线程3");
thread3.start();
thread2.start();
thread1.start();
}
- 通过创建单一化线程池newSingleThreadExecutor()实现
static ExecutorService executorService = Executors.newSingleThreadExecutor();
@Test
public void test4() {
Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "打开冰箱");
});
Thread thread2 = new Thread(() -> {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "拿出可乐" );
});
Thread thread3 = new Thread(() -> {
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "关上冰箱" );
});
executorService.submit(thread1);
executorService.submit(thread2);
executorService.submit(thread3);
executorService.shutdown();
}