线程的执行顺序

线程的执行顺序是不确定的

调用Thread的start()方法启动线程时,线程的执行顺序是不确定的。也就是说,在同一个方法中,连续创建多个线程后,调用线程的start()方法的顺序并不能决定线程的执行顺序。

例如,这里,看一个简单的示例程序,如下所示。

在ThreadSort01类中分别创建了三个不同的线程,thread1、thread2和thread3,接下来,在程序中按照顺序分别调用thread1.start()、thread2.start()和thread3.start()方法来分别启动三个不同的线程。

那么,问题来了,线程的执行顺序是否按照thread1、thread2和thread3的顺序执行呢?运行ThreadSort01的main方法,结果如下所示。

thread1

thread2

thread3

再次运行时,结果如下所示。

thread1

thread3

thread2

第三次运行时,结果如下所示。

thread2

thread3

thread1

注意:每个人运行的情况可能都不一样。

可以看到,每次运行程序时,线程的执行顺序可能不同。线程的启动顺序并不能决定线程的执行顺序。

如何确保线程的执行顺序

1.确保线程执行顺序的简单示例

在实际业务场景中,有时,后启动的线程可能需要依赖先启动的线程执行完成才能正确的执行线程中的业务逻辑。此时,就需要确保线程的执行顺序。那么如何确保线程的执行顺序呢?

可以使用Thread类中的join()方法来确保线程的执行顺序。例如,下面的测试代码。

可以看到,ThreadSort02类比ThreadSort01类,在每个线程的启动方法下面添加了调用线程的join()方法。此时,运行

ThreadSort02类,结果如下所示。

thread1

thread2

thread3

再次运行时,结果如下所示。

thread1

thread2

thread3

第三次运行时,结果如下所示。

thread1

thread2

thread3

可以看到,每次运行的结果都是相同的,所以,使用Thread的join()方法能够保证线程的先后执行顺序。

2.join方法如何确保线程的执行顺序

既然Thread类的join()方法能够确保线程的执行顺序,我们就一起来看看Thread类的join()方法到底是个什么鬼。

进入Thread的join()方法,如下所示。

可以看到join()方法调用同类中的一个有参join()方法,并传递参数0。继续跟进代码,如下所示。

可以看到,有一个long类型参数的join()方法使用了synchroinzed修饰,说明这个方法同一时刻只能被一个实例或者方法调用。由于,传递的参数为0,所以,程序会进入如下代码逻辑。

if (millis == 0) {

while (isAlive()) {

wait(0);

}

}

首先,在代码中以while循环的方式来判断当前线程是否已经启动处于活跃状态,如果已经启动处于活跃状态,则调用同类中的wait()方法,并传递参数0。继续跟进wait()方法,如下所示。

public final native void wait(long timeout) throws InterruptedException;

可以看到,wait()方法是一个本地方法,通过JNI的方式调用JDK底层的方法来使线程等待执行完成。

需要注意的是,调用线程的wait()方法时,会使主线程处于等待状态,等待子线程执行完成后再次向下执行。也就是说,在ThreadSort02类的main()方法中,调用子线程的join()方法,会阻塞main()方法的执行,当子线程执行完成后,main()方法会继续向下执行,启动第二个子线程,并执行子线程的业务逻辑,以此类推。

展开阅读全文

页面更新:2024-05-08

标签:线程   顺序   示例   逻辑   状态   参数   代码   业务   程序   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top