深入理解join方法的實現原理
有一道面試題是:
如何控制多執行緒的執行順序;
執行緒的程式碼就不貼了。上偽碼好了:
main(){
thread1.start();
thread1.join();
thread2.start();
thead2.join();
thread3.start();
}
有幾個方法都可以做到,這裡主要是套路最簡單的使用join方法,如何解決。
首先看join方法的API
這是隨手百度的 :
join()等待執行緒結束。
都是很淺的說了一下,要深入理解還是得看原始碼:
public final synchronized void josin (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方法 是一個 synchronized 的同步方法。
舉個例子,join是在main方法裡被呼叫了。
然後main方法就持有了 join方法 的 這個鎖。
然後join 方法裡面呼叫了 wait方法。
這個過程的目的是讓持有這個同步鎖的執行緒進入等待。
那麼誰持有了這個同步鎖呢?
答案就是main方法,因為main方法呼叫了join方法。
main方法就持有 synchronized 標記的這個鎖,誰持有這個鎖誰就等待。
wait()方法只會讓持有鎖的執行緒進入等待,而啟動執行緒的 start() 並沒有持有鎖,所以
strat方法還是會執行,而join方法中的wait方法 使main 方法等待了。
所以main方法就沒有獲取到CPU資源,
所以main方法中的 thread2 就沒有辦法獲取CPU資源。
然後join方法執行完之後,不用想,JVM底層肯定執行了 notify的操作。
網上copy來的jvm程式碼
//一個c++函式:
void JavaThread::exit(bool destroy_vm, ExitType exit_type) ;
//這傢伙是啥,就是一個執行緒執行完畢之後,jvm會做的事,做清理啊收尾工作,
//裡面有一個賊不起眼的一行程式碼,眼神不好還看不到的呢,就是這個:
ensure_join(this);
//翻譯成中文叫 確保_join(這個);程式碼如下:
static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj());
ObjectLocker lock(threadObj, thread);
thread->clear_pending_exception();
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
java_lang_Thread::set_thread(threadObj(), NULL);
//thread就是當前執行緒main執行緒啊。
lock.notify_all(thread);
thread->clear_pending_exception();
}
notify_all 之後 join方法結束,自然 main方法又獲取到cpu資源了,然後thread2又可以取得cpu資源,然後又是這個過程。
大概就是這樣了
相關推薦
深入理解join方法的實現原理
有一道面試題是: 如何控制多執行緒的執行順序; 執行緒的程式碼就不貼了。上偽碼好了: main(){ thread1.start(); thread1.join(); thread2.start(); thead2.join(); thread3.st
深入理解Git的實現原理
原文地址:https://www.cnblogs.com/mamingqian/p/9711975.html 0、導讀 本文適合對git有過接觸,但知其然不知其所以然的小夥伴,也適合想要學習git的初學者,通過這篇文章,能讓大家對git有豁然開朗的感覺。在寫作過程中,我力求
深入理解 Dijkstra 演算法實現原理
迪傑斯特拉(Dijkstra)演算法 1典型最短路徑演算法,用於計算一個節點到其他節點的最短路徑。 2特點是以起始點為中心向外層層擴充套件(廣度優先搜尋思想),直到擴充套件到終點為止。 大概就是這樣一個有權圖,Dijkstra演算法可以計算任意節點到其他節點的最短
深入理解ArrayList集合內部原理並自主封裝程式碼實現ArrayList集合功能
集合框架是java基礎學習中非常重要的一部分,學會集合用法的同時去了解一下集合內部程式碼實現原理對我們日後的java學習的幫助是十分大的;我們現在來了解一下ArrayList原理:ArrayList內部其實就是封裝一個預設固定大小的物件陣列;不過陣列的大小是可動
iOS底層原理總結-- 深入理解 KVC\KVO 實現機制
iOS底層原理總結–OC物件的本質(一) - 掘金 iOS底層原理總結–OC物件的本質(二) - 掘金 iOS底層原理總結–OC物件的分類:instance、class、meta-calss物件的isa和superclass - 掘金 iOS底層原理總結-- KVO/KVC的本質
深入分析Volatile的實現原理
queue 鏈接地址 什麽 高速緩存 spa 其中 帶來 系統內存 單詞 引言 在多線程並發編程中synchronized和Volatile都扮演著重要的角色,Volatile是輕量級的synchronized,它在多處理器開發中保證了共享變量的“可見性”。可見性的意思是當
深入分析synchronized的實現原理
test 代碼塊 mage this rgs 需要 pub 釋放 javap 基礎概念 synchronized可以保證方法或者代碼塊在運行時,同一時刻只有一個方法可以進入到臨界區,同時可以保證共享變量對內存可見性。 Java中每一個對象都可以作為鎖,這是syn
深入理解flutter的編譯原理與優化
bottom 熱更新 pre ted 符號 註釋 跟蹤 data 傳遞 摘要: 閑魚技術-正物 問題背景 對於開發者而言,什麽是Flutter?它是用什麽語言編寫的,包含哪幾部分,是如何被編譯,運行到設備上的呢?Flutter如何做到Debug模式Hot Reload快速生
深入分析Zookeeper的實現原理
技術分享 png 還需要 可能性 依賴 分布 共享 思考 小文件 zookeeper 的由來 分布式系統的很多難題,都是由於缺少協調機制造成的。在分布式協調這塊做得比較好的,有 Google 的 Chubby 以及 Apache 的 Zookeeper。Google C
深入理解 MySQL 底層實現
MySQL 的常用引擎 1. InnoDB InnoDB 的儲存檔案有兩個,字尾名分別是 .frm 和 .idb,其中 .frm 是表的定義檔案,而 idb 是資料檔案。 InnoDB 中存在表鎖和行鎖,不過行鎖是在命中索引的情況下才會起作用。 InnoDB 支援事務,且支援四種隔離
深入理解PHP Opcode快取原理
什麼是opcode快取? 當直譯器完成對指令碼程式碼的分析後,便將它們生成可以直接執行的中間程式碼,也稱為操作碼 (Operate Code,opcode)。Opcode cache的目地是避免重複編譯,減少CPU和記憶體開銷。 如果動態內容的效能瓶頸不在於CPU和記憶
跟廠長學PHP7核心(八):深入理解字串的實現
在前面大致預覽了常用變數的結構之後,我們今天來仔細的剖析一下字串的具體實現。 一、字串的結構 struct _zend_string { zend_refcounted_h gc; /* 字串類別及引用計數 */ zend_ulong h; /* 字
深入理解synchronized方法同步的是方法還是物件?
一.運用synchronized關鍵字 首先我們來看看一個多執行緒中執行緒不安全的列子 程式碼如下: 共享資料類: public class NotSynchronizated extends Thread { private int num =10; @Override publi
一篇文章通透理解序列號實現原理
1.序列號的本質序列號等價於註冊碼,是軟體發行商的一種維權手段,也就是正版軟體的一個身份證。本質:防止盜版、按功能收費等。 目前,商用軟體和共享軟體絕大部份都是採用註冊碼授權的方式來保證軟體本身不被盜用,以保證自身的利益。儘管很多常用的許多軟體系統的某些版本已經被別人
聊聊併發(一)深入分析Volatile的實現原理
引言 在多執行緒併發程式設計中synchronized和Volatile都扮演著重要的角色,Volatile是輕量級的synchronized,它在多處理器開發中保證了共享變數的“可見性”。可見性的意思是當一個執行緒修改一個共享變數時,另外一個執行緒能讀到這個修改的值。它在某些情況下比syn
深入解析Vue底層實現原理
本次給大家整理Vue底層實現原理的知識點總結,寫的十分的全面細緻,具有一定的參考價值,對此有需要的朋友可以參考學習下。如有不足之處,歡迎批評指正。 前言 最近在研究 剖析Vue原理&實現雙向繫結MVVM 這篇文章,一邊學習一邊總結一下自己的思考。 Vue是一個典型的MVV
【死磕Java併發】- 深入分析volatile的實現原理
通過前面一章我們瞭解了synchronized是一個重量級的鎖,雖然JVM對它做了很多優化,而下面介紹的volatile則是輕量級的synchronized。如果一個變數使用volatile,則它比使用synchronized的成本更加低,因為它不會引起執行緒上下文的切換和排程。Java語言
equals()和HashCode()深入理解以及Hash演算法原理
1.深入理解equals(): 在我的一篇部落格“==”和.equals()的區別中向讀者提出提醒: Object類中的equals方法和“==”是一樣的,沒有區別,即倆個物件的比較是比較他們的棧記憶體中儲存的記憶體地址。而String類,Integer類等等一些類,是
深入理解Spring--動手實現一個簡單的SpringIOC容器
package com.wang.main; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.M
深入解析React Event實現原理
React 元素的事件處理和 DOM元素的很相似。但是有一點語法上的不同: React事件繫結屬性的命名採用駝峰式寫法,而不是小寫。 如果採用 JSX 的語法你需要傳入一個函式作為事件處理函式,而不是一個字串(DOM元素的寫法) 並且 React 自己內部實現了一