问题:给定三个线程 A B C 怎么让 A-B-C 三个线程按照顺序执行完?
问题分析:按照指定循序执行,也就是说线程A执行完再执行线程B,线程B执行完再执行线程C.
如何实现?通过 join() 方法就可以实现:
public static void main(String[] args) throws Exception {
// 创建三个线程 A, B C
Thread threadA = new Thread(() -> {
System.out.println(Thread.currentThread() + "执行");
}, "线程A");
Thread threadB = new Thread(() -> {
System.out.println(Thread.currentThread() + "执行");
}, "线程B");
Thread threadC = new Thread(() -> {
System.out.println(Thread.currentThread() + "执行");
}, "线程C");
threadA.start();
threadA.join();
threadB.start();
threadB.join();
threadC.start();
threadC.join();
}
运行结果如下:
Thread[线程A,5,main]执行
Thread[线程B,5,main]执行
Thread[线程C,5,main]执行
Process finished with exit code 0
从运行结果来看,确实符合要求,那这是为什么呢,原理是什么呢?
执行过程分析:
main 线程启动开始从上到下执行,首先创建三个线程 A,B,C 然后开始执行threadA.start();
这时候 线程A调用native start0(),启动一个线程,然后执行 线程A run方法,即执行:System.out.println(Thread.currentThread() + "执行");
,执行完后 main 线程开始执行threadA.join();
源码如下:
public final void join() throws InterruptedException {
join(0);
}
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;
}
}
}
由于millis ==0,所以会执行以下代码:
if (millis == 0) {
while (isAlive()) {
wait(0);
}
}
通过以上代码,你可能会发现这不是死循环吗,什么时候
isAlive()
为false
呢? main线程开始执行该代码发现isAlive()
方法 也是native
方法,赶紧打开JVM 源码查找,发现isAlive
定义(Thread.c):
static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},
{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
{"isAlive", "()Z", (void *)&JVM_IsThreadAlive},
此处省略。。。
};
// JVM_IsThreadAlive 方法实现
JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread))
JVMWrapper("JVM_IsThreadAlive");
oop thread_oop = JNIHandles::resolve_non_null(jthread);
return java_lang_Thread::is_alive(thread_oop);
JVM_END
// is_alive 实现
bool java_lang_Thread::is_alive(oop java_thread) {
JavaThread* thr = java_lang_Thread::thread(java_thread);
return (thr != NULL);
}
以上方法主要是判断当前线程是否存活,很显然当前线程mian线程处于运行状态,所以
isAlive()
为true
,然后开始执行wait(0)
方法,main线程进入进入等待队列,等待被唤醒,那么什么时候被唤醒呢? 通过上一篇文章: 线程启动:源码的理解可以知道创建线程后会执行 线程的的 run 方法 线程 执行完后会调用线程的退出方法:
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
assert(this == JavaThread::current(), "thread consistency check");
HandleMark hm(this);
Handle uncaught_exception(this, this->pending_exception());
this->clear_pending_exception();
Handle threadObj(this, this->threadObj());
assert(threadObj.not_null(), "Java thread object should be created");
if (get_thread_profiler() != NULL) {
get_thread_profiler()->disengage();
ResourceMark rm;
get_thread_profiler()->print(get_thread_name());
}
// 此处省略非关键代码
// Notify waiters on thread object.
// 唤醒等待的线程
ensure_join(this);
static void ensure_join(JavaThread* thread) {
// We do not need to grap the Threads_lock, since we are operating on ourself.
Handle threadObj(thread, thread->threadObj());
assert(threadObj.not_null(), "java thread object must exist");
ObjectLocker lock(threadObj, thread);
// Ignore pending exception (ThreadDeath), since we are exiting anyway
thread->clear_pending_exception();
// Thread is exiting. So set thread_status field in java.lang.Thread class to TERMINATED.
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
// Clear the native thread instance - this makes isAlive return false and allows the join()
// to complete once we've done the notify_all below
//清理本地线程实例,设置 isAlive 为 false
java_lang_Thread::set_thread(threadObj(), NULL);
// 唤醒线程
lock.notify_all(thread);
// Ignore pending exception (ThreadDeath), since we are exiting anyway
thread->clear_pending_exception();
}
分析线程退出代码,发现:
isAlive=false
,这样跳出while(isAlive()){wait(0)}
,main线程被唤醒,然后接着继续往下执行.threadB.start(); threadB.join(); threadC.start(); threadC.join();
重复以上执行过程,就得到了我们想要的分析结果。
如果您觉得该文章对您有帮助,点个赞就好,也可以分享给你朋友,如果写的不好还请多包涵,咱们可以探讨交流: qq:786063250
网友评论