概述
Thread类的方法中有一个join()方法,它是普通的实例方法,根据Java api,该方法有如下三种形式:
void join(): Waits for this thread to die.
void join(long millis): Waits at most millis milliseconds for this thread to die.
void join(long millis, int nanos): Waits at most millis milliseconds plus nanos nanoseconds for this thread to die.
该方法的作用是“等待该线程终止”,一直等待,直到程终止,而带参数的方法的作用是“ 等待该线程终止,至多等待多少毫秒数 (或毫秒数+纳秒数)”。
在此之前,我对这个方法一直有两个疑问,困惑不解:
- 为什么这个方法的作用是等待该线程终止,为什么它的名字是“加入”的意思?
- 在这个等待的关系中,到底是谁等待谁?
在看了很多人的博客、看了这个方法的源码、看了《Java多线程编程核心技术》这本书和实践之后,我的理解如下,作为自我学习总结。
1. join()的源码分析
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(long millis)
方法的源代码如上所示,首先该方式是synchronized,其次它的实现原理是调用了wait()方法。
2. join()/wait()与sleep()的区别
由上,所以join()和sleep()
这两个方法的区别,本质上是wait()和sleep()
这两个方法的区别。
wait()和sleep()的区别:
- 这两个方法来自不同的类,wait()方法来自Object类,sleep()方法来自Thread类;
- wait()方法有三种形式:
wait()、wait(long timeout)、wait(long timeout, int nanos)
,而sleep()方法两种形式:sleep(long millis)、sleep(long millis, int nanos)
,即sleep()方法没有无参形式。其次,sleep()方法是静态方法。 - 其实区别主要还是来自于这两个方法对同步的处理上:wait()方法会释放锁,sleep()方法不释放锁。在sleep()方法的源代码中有这样一句话:
The thread does not lose ownership of any monitors.
所以join()和sleep()
这两个方法的区别,来自于它们对同步的处理上,如上第三条。
3. join()的作用分析
join()方法具有使线程依次串行执行的作用,也就是使线程排队运行。对于t.join()语句,其中的等待关系如下:
join()方法的作用是使线程t正常执行run()
方法中的任务,而使当前线程s一直等待线程t终止,
在很多情况下,主线程生成并起动了子线程,所以线程s有可能是主线程,也有可能是其它子线程。
也就是t.join()方法后面的代码,只有等到t线程结束了才能执行。join()方法的使用方式是在线程t启动后直接调用。
代码实例:
功能:三个线程,一个打印A,一个打印B,一个打印C,打印出6个连续的ABC。
/*
* 三个线程, 一个打印A, 一个打印B, 一个打印C, 打印出6个连续的ABC.
*/
public class PrintABC implements Runnable {
@Override
public void run() {
if(Thread.currentThread().getName().equals("A")){
System.out.print("A");
}
if(Thread.currentThread().getName().equals("B")){
System.out.print("B");
}
if(Thread.currentThread().getName().equals("C")){
System.out.print("C");
}
}
public static void main(String[] args) throws InterruptedException {
for(int i=0; i<6; i++){
PrintABC r = new PrintABC();
Thread A = new Thread(r, "A");
A.start();
A.join();
Thread B = new Thread(r, "B");
B.start();
B.join();
Thread C = new Thread(r, "C");
C.start();
C.join();
}
}
}
运行结果:
嘻嘻~
最后
以上就是美丽小熊猫为你收集整理的多线程——join()、sleep()的全部内容,希望文章能够帮你解决多线程——join()、sleep()所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复