1.基本概念
查看注释
Waits for this thread to die.
一个线程一旦调用了join方法,那么在执行顺序上,必须等ta执行完才会继续调用启动它的线程
2.源码
查看源码可知join方法也是用wait来实现的
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;
}
}
}
3.疑问:既然是调用wait方法实现的,那么notify在何处呢?
我们可以看到线程退出时的实现:
static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj());
assert(threadObj.not_null(), "Java thread object must exist");
ObjectLocker lock(threadObj, thread);
thread->clear_pending_exception();
java_lang_Thread::set_stillborn(threadObj());
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
java_lang_Thread::set_thread(threadObj(), NULL);
lock.notify_all(thread);
thread->clear_pending_exception();
}
也就是说,唤醒是在native层线程退出的时候做的。
4.使用join方法实现线程的顺序执行
public class Main {
public static void main(String args[]) {
Thread a = new Thread() {
public void run() {
System.out.println("thread a 执行");
}
};
Thread b = new Thread() {
public void run() {
System.out.println("thread b 执行");
}
};
Thread c = new Thread() {
public void run() {
System.out.println("thread c 执行");
}
};
Thread d = new Thread() {
public void run() {
System.out.println("thread d 执行");
}
};
Thread e = new Thread() {
public void run() {
System.out.println("thread e 执行");
}
};
Thread f = new Thread() {
public void run() {
System.out.println("thread f 执行");
}
};
try {
a.start();
a.join();
b.start();
b.join();
c.start();
c.join();
d.start();
d.join();
e.start();
e.join();
f.start();
f.join();
} catch (InterruptedException error) {
// TODO Auto-generated catch block
error.printStackTrace();
}
}
}
5.一道编程题
public static void main(String args[]) {
for (int i = 0;i<2000;i++) {
final int j = i;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(j);
}
}).start();
}
}
问打印结果会如果,应该如何修改
答:打印结果会比较散乱
修改:
public static void main(String args[]) {
for (int i = 0;i<2000;i++) {
final int j = i;
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(j);
}
});
try {
thread.start();
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这样修改了之后,打印结果就是有顺序的了。
参考:https://blog.csdn.net/erica_1230/article/details/69388742