1
现在的编程语言大多数是支持并发编程,多线程的,当实现多线程时,如何保证各个线程的执行次序呢?
比如现在有线程A,线程B,线程C,如何保证线程按照A->B->C的顺序执行呢?
如下代码所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class ThreadJoinTest {
public static void main(String[] args) {
Thread A = new Thread(() -> System.out.println("A")); Thread B = new Thread(() -> System.out.println("B")); Thread C = new Thread(() -> System.out.println("C"));
A.start(); B.start(); C.start();
} }
|
通过测试,此时,执行结果是不一定的,A,B,C的次序是随机的,如下图两次执行结果就分别是B-C-A,C-B-A。
那么,如何保证线程按照指定的次序A-B-C来执行呢?
Thread.join函数
通过调用Thread.join函数我们可以实现按照指定次序执行。我们先来看一下Thread.join函数的解释:
Waits for this thread to die.
An invocation of this method behaves in exactly the same way as the invocation
等待这个线程死亡。
调用此方法的行为方式与调用完全相同。
解释有些看不懂。我们可以这样理解,线程调用join时,会造成主线程等待调用线程死亡后才接着执行后续代码。
我们来看看修改后的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class ThreadJoinTest { public static void main(String[] args) throws InterruptedException { Thread A = new Thread(() -> System.out.println("A")); Thread B = new Thread(() -> System.out.println("B")); Thread C = new Thread(() -> System.out.println("C"));
A.start(); A.join(); B.start(); B.join(); C.start(); C.join();
} }
|
执行结果:
而且,不管该程序执行多少次,执行结果总是一定的,一定是按照次序A-B-C来执行。
我们来看一下join函数做了什么?
1 2 3
| public final void join() throws InterruptedException { join(0); }
|
join()函数调用实际是调用join(0),我们继续看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0;
if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); }
if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
|
调用join函数时,millis=0,即我们实际执行的重要代码主要是下面这一部分:
1 2 3
| while (isAlive()) { wait(0); }
|
其中isAlive()方法判断线程是否仍然在执行而没有die,如果仍然在执行,则主线程执行wait,直到线程结束才继续执行后续代码。
除了Join函数外,是否有其他方式保证执行顺序呢?我们之后介绍