分類
發燒車訊

一條update SQL語句是如何執行的

  一條更新語句的執行過程和查詢語句類似,更新的流程涉及兩個日誌:redo log(重做日誌)和binlog(歸檔日誌)。比如我們要將ID(主鍵)=2這一行的值加(c:字段)1,SQL語句如下:

update T set c=c+1 where ID=2;
  • redo log

  重做日誌是InnoDB引擎特有的,是物理日誌,記錄在“某個數據頁上做了什麼修改“。大小是固定,可以進行配置大小。假如我們配置一組4個文件,圖中write pos是當前記錄的位置,往後推移並且循環;checkpoint是當前要擦除的位置,移動規律和前者一樣。兩者之間的位置可以記錄新的操作

  

  如果write pos 追上checkpoint,就移動checkpoint擦除一些記錄。所以即使數據可以發生異常重啟,InnoDB也可以保證之前提交的記錄不會丟,這就是MySQL的crash_safe能力。

  • binlog

   歸檔日誌是MySQL的server層的實現的,所有引擎都可以使用。binlog記錄的是sql語句的原始邏輯,比如根劇’id’字段查詢所有的信息;相比redo log的循環寫入,binlog是追加寫的,binlog文件寫到一定大小後會切換到下一個,不會覆蓋以前的日誌。

  Binlog有兩種模式,statement 格式的話是記sql語句, row格式會記錄行的內容,記兩條,更新前和更新后都有。

 文章開頭的更新語句在InnoDB中的執行流程如下:深色代表在執行器中執行的,淺色是在存儲引擎中。

  最後寫入redolog分為了prepare和commit兩步,用來保證兩個日誌寫入的一致性,這就是“兩階段提交”。比如我們執行“update T set status = 1“時:

  • 如果寫入redolog成功,但寫binlog失敗,重啟恢復時,數據庫發現沒有commit,那麼事務本身回滾;備份恢復時沒有binlog,數據庫里的status值不變。
  • 如果在commit失敗,重啟恢復時redolog和binlog一致,重新commit;備份恢復時有binlog,直接恢復。

  總的來說binlog記錄了對數據庫所有的邏輯操作,可以通過binlog來備份出一份完全相同的庫;因為redolog是InnoDB引擎特有的,如果使用其他引擎,那麼就要依賴binlog來記錄操作。

Q定期全量備份的周期“取決於系統重要性,有的是一天一備,有的是一周一備”。那麼在什麼場景下,一天一備會比一周一備更有優勢呢?或者說,它影響了這個數據庫系統的哪個指標?

A一天一備,那麼如果需要恢複數據的話,只要保證當天的binlog完整即可;一周一備的話就要保證一周的binlog完整;同時頻繁全量備份需要更多存儲空間,如何選擇取決於業務的重要性,對應的指標是RTO(目標恢復時間)。

 — 《MySQL實戰45講》筆記二

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

分類
發燒車訊

畢業了,我的四年大學:平凡但不平庸(寫給每一位想要認真學習的小夥伴)

去年十月份的時候,我分享了一篇關於我三年大學的文章:普普通通,我的三年大學,說實話,這篇文章還是激勵了不少小夥伴,給很多人帶來了動力。寫這篇那會,我剛結束了自己的秋招,結束秋招的那一刻,可以說是 2019 年心情最放鬆的時刻了,對於沒有讀研的學生來說,秋招那一戰,可以算是整個大學最重要的一戰了,在這裏,也希望各位小夥伴,也要早點做好準備。

時間是過的真快,一不小心就在公司實習了差不多三個月了,大學最後的作業 —- 答辯和論文,也都處理完畢了,可以說我的大學,即將要畫上一個句號了。

我的四年大學,可以說是普普通通,在校期間也沒啥輝煌的戰績,更準確的說是,0 戰績:沒有參加過什麼大賽,甚至沒有參加過比賽;在學校也沒拿過獎學金,連個三好學生都不給;也沒去用心融入一個社團,成為裏面的一員;更沒有去做過兼職,發過海報。

但正是因為普普通通,我才要分享自己的四年大學。一個簡單的原因就是,我的公眾號里有 65% 是在校生,並且我相信大部分人和我一樣,都是普普通通,所以我希望我在大學的做法,或許可以給你們一個參考。不過說實話,雖然我的大學沒有什麼輝煌的戰績,但我還算滿意,至少是按照我自己的計劃走過來的,並且自己的目標也都實現了。

大一

大一第一學期這部分的事情最多了,所以會寫的多一些,因為我覺得,在大一,我的思維發生了很大的改變,大一過後,我的想法、計劃就基本有着落了,後面基本事按照自己的計劃,去做自己喜歡的事了。

大一第一學期的第一要務:轉專業

看過我之前文章的讀者可能都知道,我大一第一學期不是計算機專業的,讀的專業是木材科學與工程。當然,這不是我自己選擇的專業,而是高考分數不夠,被調劑的專業,我自己熱愛的專業是計算機類專業,還沒有進入大學之前,我就說我一定要讀編程相關的專業了。

說實話,我很慶幸自己最後轉到了計算機類的專業,一個很現實的原因就是,學編程,真的能夠掙錢,而且你願意努力學的話,你一畢業就能夠拿到很高的工資,本科畢業,有好些可以拿到年薪 50 萬,你敢信?就算工資很低,也都能年薪十幾萬,當然,我不能暴露自己的工資,暴露了就要被公司勸退了。

是的,我讀計算機專業,有兩個重要的原因,一個原因就是熱愛,一個是家裡窮,我想掙錢,改變家裡的現狀。所以在我大一第一學期那一會,我的目標就很明確,這學期的任務就是轉專業,所以我了解了轉專業的各種規則,了解到轉專業的一個最基本的要求就是數學和英語需要 85 分以上才能參与考試。

85 分很難嗎?不難;但是如果需要你保證 85 分難嗎?說實話,有一些,因為萬一考不好呢?考不好就得大二轉了,所以我第一學期,英語的平時分,我給刷到了 100 分,也就是滿分。數學是我的強項,但我依然不敢掉以輕心,在考前把 2006-2015 年的試卷都刷了一兩遍。

有這樣的準備,數學和英語的分數那必須杠杠,實不相瞞,大一學期的績點是我整個大學的巔峰,然而,三等獎依然沒有拿到!!!因為我只學了這兩門,其他隨意,不掛科即可。

當然,85 分只是一個門檻,轉專業的競爭還是挺激烈。我選了軟件工程,參与人數大概是差不多 60 人,不過學院只接 15 個人(後來好像是錄取了 20 人),所以為了穩一些,我在第一學期就把 c 語言自學了一遍,把學校的 OJ 題庫,第一學期相關的編程題,給刷了一兩遍。

說實話,有了這樣的準備,轉專業想不成功都難,考試 2 小時,我不到半個小時就離開考場了,然而我居然是第三個離開考場的,而不是第一個。第一個和第二個離開考場的,單挑嗎?

有必要加入社團嗎?

對於剛步入大學的同學來說,社團是一個比較有趣的玩意,絕大部分人都會去加入自己喜歡的社團吧。

我進入大學之前,很多人說,在大學,要多交點人脈,多認識一些朋友,因為這些人會成為你後面很重要的資源,所以我去加入一些社團,其實是想多認識一些人,然而,我去面試了兩個社團,都在二面被刷了,說實話,對於面試,我還是有點恐懼的,反正就是挺緊張,後來我就乾脆不去面試了,不加入社團了。

後來我就加入了他們的會員,之前面試那個,是成為他們的幹部。成為會員則不需要面試,不過需要交會員費用,所以我就順便成為了幾個社團的會員,例如羽毛球,愛心社團啥的。

不過,我去參与了一兩次社團的活動之後,就沒在去了,一個簡單的原因就是,我不大喜歡,我還是喜歡去做自己喜歡的事。我是一個懶散,喜歡自由,不喜歡被束縛的人,所以我覺得,我還是不去參加這些活動了。

回答剛才的問題,有必要加入社團嗎?,可能很多人會覺得,必須要加入社團,不然大學就不完整了,我的想法則是,加入社團不是一個必選項,加與不加,我覺得都沒事,看你自己的喜歡。加入社團能學到很多東西嗎?能學到一些,但這些沒啥的,對於以後找工作,我覺得屬於可有可無。如果你自己願意學習,學習能力比較強,在哪裡都可以學到很多東西。

擺脫的社團之後,我基本就什麼組織也沒參加了,然後我宿舍也有一個和我一樣比較逗比+沙雕的,我倆就經常去外面溜達,看到有趣的活動,就去參与一波,反正完全看心情,報名了活動,交了錢,心情不好就不去參加了,美滋滋(感覺要被噴,哈哈)

有必要多認識些人嗎?

我剛才說了,我希望自己在大學多認識些人,多泛交些朋友,後來經過第一學期的感悟,我發現,這沒必要,在大學,大家基本都在忙各自的事情,我本來還想在大學找幾個摯友,以後一起干大事,但經過一學期的觀察,發現這很難,當然,很難不代表不存在。

總之,對於現在還在大一大二的學生,如果你有這方面的疑問,那麼我給的建議是,沒必要刻意去交朋友,其實後面大家都各自去做自己的事情了,畢竟找到一些經的起時間考驗的志同道合的朋友,很不容易。

第二學期:落差之后的折騰

大一學期其實可以寫的還有非常非常多,因為第一學期,我的任務就兩門課程,還是非常閑,期間也發生了非常多改變我想法多事情,不過一不小心就兩千多字了,還是不繼續寫了,後面的時光可能就沒有第一學期那麼豐富了,相對比較枯燥了。

經過了第一學期,成功進入了軟件工程,自己也沒參与什麼社團,並且大學想要干點事,例如創業之類的,因為沒讀大學之前,經常聽說創業這事……總之,進入大學的時候,感覺前途一片光明,我覺得我要干非常非常多的事,但進入大學之後,發現並沒有啥戰績。

慶幸的事,我完成了一個非常堅定的目標,那便是轉專業。轉過來軟工之後,我也想干點大事,例如 acm 拿個牛逼的獎牌,或者寫個牛逼的軟件出來,因為經常聽到某某人開發了一個 xx,然後就成名了。

然而,學了 c 語言,發現啥也寫不出來,學了算法,發現 acm 那些題也太難了,一道題做一天,還是沒做出來,答案也看不懂,發現自己並不是大神,腦子也並沒有大佬轉的快。

後來,我就不打算參加 acm 了,感覺如果自己要拿到名次,肯定會花很多時間,並且不一定拿的到,加上我看到班裡也有人退出 acm 集訓隊了,這更加堅定了我的想法。

聽說數據結構與算法很重要,所以我早早就把數據結構與算法這門課學完了,我第二學期學的最多的就是數據結構 + 算法這兩門課,雖然不參加 ACM,但算法還是得學,會點算法聽說會顯的牛逼一些。

暑假的折騰

大一暑假那會,雖然數據結構與算法學的還不錯,不過發現啥東西的做不出來,C 語言寫的程序都是黑乎乎的界面,然後我就學了 windows 程序編程,這樣我就可以寫個程序給身邊的人玩了,畢竟我是學編程的,至少得寫個作品出來給別人玩啊。

在暑假花了十幾天,把那本 900 多頁的windows程序編程刷了 700 多頁,寫了個計算器,後來發現身邊的人還是玩不了,因為很多人沒電腦,於是我就對 windows 編程沒興趣了,想着寫個程序能夠在手機運行就好了,於是花了十幾天學了 android 編程,刷完了《第一行代碼》這本書,順便入門了 Java,跟着書寫了個天氣預報,還是挺開心。

不過我又改變主意了,想着要是能掙到錢就更好了,於是我發現把 app 上傳到商店,然後植入廣告,就可以掙錢了,於是我買了一些實戰類 android 項目的書籍,寫了幾個 app,自己改版之後傳到了應用商店。

然而,沒啥人下載,於是我又放棄搞安卓了,後來想寫個網站,然後放一些資源,讓別人來下載好像也有機會掙錢,於是我學習了 HTML,CSS,JavaScript,然後又不了了之……

這兩個月的暑假,我感覺自己搞了好多東西,好多都是半途放棄,實不相瞞,驅動我去折騰這些事有兩個原因:掙錢 + 裝逼。說實話,我做什麼事情,都需要驅動力,我覺得驅動力對我來說太重要了,這個驅動力可以很虛,但必須得有,而我又是一個俗人,能夠掙錢,是我最大的驅動力。當初我玩斗地主,驅動力是掙 Q 幣,後來我發現這些 Q 幣好像不能充 QQ會 員還是怎麼的,我就放棄不玩了。

這段折騰,我覺得讓我慢慢摸清了自己的方向,所以在這裏,對於大一或者大二的同學,如果你們有自己感興趣的,或許可以去嘗試一波。別人可能會說,這搞一下,那搞一下,會導致樣樣都會,但樣樣不精。而我的想法是:完全可以去嘗試,大學的學習,不存在精通這一說法,大一大二多嘗試,大三確定自己的方向來學習完全來得及。

大二

經過大一的洗禮,我覺得我的目標相對比較明確了,該玩的玩了,該折騰的折騰了,現在得好好規劃下自己的未來了。我了解到校招時大廠非常看重基礎,於是我大二就一直在學習基礎,例如計算機網絡,算法,操作系統這些,怎麼學?

得有動力啊,於是我報名了中級軟考,這算是我一個動力,這門考試會考整個大學涉及到的知識,於是為了搞定這個軟考,我大二把很多課程都學了,後面軟考也順利通過了。

中級軟考有必要參加嗎?答是隨便,這個證沒啥含金量的,我的目的是讓他督促我學習基礎知識,適合用來複習知識吧。

總之,大一,我學了很多數據結構和算法相關知識,大二,我學了很多基礎知識 + Java 的知識,並且大二比較專心,啥比賽,啥活動也沒參加,我說了,我喜歡做自己喜歡做的事,喜歡跟着自己的步伐走,別人的建議,我可能會參考下,但我無論做什麼事,都有自己的想法和思考。

有人也有問,有必要加入實驗室嗎?,我沒加過實驗室,但我想說的是,加與不加,都沒關係,重點是你想學習什麼,想成為什麼樣的人,實驗室,更多的是一種氣氛,但不一定適合你。要是我加入實驗室,我可能會把實驗室當作一個學習的場地,進而去學習自己喜歡的東西。

也有人問,那些基礎知識很枯燥,有沒有什麼辦法?,答是沒有,有些本來就枯燥,但枯燥的東西,往往是決定你我之間的區別,如果都很有趣,那大家肯定也都學,正是因為困難,所以才有了人與人之間的區別。

大三

其實我大三基本就處於複習 + 寫作 + 運營公眾號了,關於寫作和運營公眾號這個事,我不想說太多,因為我覺得我可以再寫兩篇文章來說這些事了。我只能說,運營一個公眾號,很不容易,我希望你,好好積累,好好準備秋招或者考研。我之所以能夠在大三寫出那麼多原創文章,一個很重要的原因就是,我大一大二積累了很多,所以大三就輸入的很少,基本處於輸出和折騰公眾號的過程。

大三的第二學期就是春招了,也就是找暑假實習,不過在大三,一般都面臨兩個選擇:讀研 還是 找工作?,實不相瞞,我從來沒想過讀研,讀研從來都沒在我的字典里。

為什麼?

之前也有挺多小夥伴問我為什麼沒讀研的,不過這個話題,我覺得我可以寫一篇關於我自己為何沒有讀研的原因了,如果你們感興趣,我後面寫一篇吧。

總的來說就是,大三處於複習的過程,之前我也曬過自己的思維導圖:當初為了有機會進大廠,帥地狠心複習了這9門核心知識,熬夜整理成思維導圖送給大家

不過說實話,其實我大三花在寫文章 + 弄公眾號的時間,佔比非常非常多,公眾號給我的學習狀態,帶來了很多負面影響,但幸運的是,我的公眾號做的不錯,給我帶來了不少收入,同時也幫忙了不少人,很多人都來感謝過我,這讓我很開心。

大三,能說的太多,但更多的都是非技術學習,我這裏就不說了,這篇文章字數也挺多了,有機會後面再說。

大四

大三暑假,也就是 2019 年 9月份,我就結束了自己的秋招了,很幸運,找到了自己喜歡的公司與城市,2019 年這一年,真的可以說是非常幸運,找到了工作 + 有了自己的公眾號,所以大四,過的很輕鬆,畢竟沒有找工作的壓力,所以大四上學期,都是在 玩 + 為工作準備 + 運營公眾號

到了大四第二學期,也就是 2020 年的 2 月份底,我就來公司實習了,一直實習到至今,關於實習到感悟,有機會再寫篇文章吧。

總結

說實話,我的大學,0 比賽 0 獎學金 0 證書,算是平凡但不平庸,但我始終都有一個明確目標支撐我去學習與探索,總的來說就是,我的大學做對了三件事,一是選擇了編程,二是學習正確的技能,三是入坑了寫作。

說實話,如果你們願意學習,你們也是可以做到的,至少,你們畢業后的薪資會對的起你們平時的學習。

我是帥地,一個即將畢業,步入社會大學的學生,希望在未來,我們共同成長,也歡迎大家見證我的成長!

最後,獻上我備戰校招的思維導圖 + 提升內功的 PDF 吧

九大思維導圖助你拿到心儀的 offer

打開計算機網絡的思維導圖長這樣

由於鏈接容易失效,不方便更新,大家可以在我的微信公眾號帥地玩編程回復思維導圖,即可獲取九大思維導圖,相信一定可以在面試時助你一臂之力。

作者簡潔

作者:大家好,我是帥地,從大學、自學一路走來,深知算法計算機基礎知識的重要性,所以申請了一個微星公眾號『帥地玩編程』,專業於寫這些底層知識,提升我們的內功,帥地期待你的關注,和我一起學習。 轉載說明:未獲得授權,禁止轉載

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

分類
發燒車訊

BMW i3 在美銷量 首度超越 Tesla Model S

 

BMW i3 純電動汽車今年 8 月在美銷量為 1,025 輛,首次超過特斯拉 Model S,後者 8 月銷量僅為 600 輛。

寶馬 i3 純電動車型在美國市場已上市 3 個月,之前由於寶馬內部的運轉效率問題,其銷量一直低於特斯拉 Model S。但該問題解決後,寶馬 i3 的銷量也迎頭趕上。特斯拉 8 月整體需求較去年同期下降 54%,7 月更是下降了 72%。與 2013 年同期相比,特斯拉今年上半年銷量下降了 26%。

專家稱,特斯拉目前正處發展壯大的階段,而寶馬在歐洲和亞洲市場則以紮穩腳跟。在產品創新度、更新速度及售價方面,特斯拉 Model S 的優勢愈來愈不明顯,而隨著寶馬 i3 的銷量逐步上升,預計歐洲將會成為其最大銷售市場。

 

(圖片來源:)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

分類
發燒車訊

日產瞄準中國電動車市場 目標拿下 20% 市占

  日本汽車大廠日產汽車(Nissan)10 日宣佈,旗下中國大陸合資公司東風汽車有限公司的乘用車部門「東風日產乘用車公司(以下稱東風日產)」自 10 日起將在大陸開賣東風日產自有品牌電動車「Venucia e30」,售價為 26 萬 7,800 元人民幣,目標為在 2018 年於中國電動車市場拿下 20% 市佔率。   Venucia e30 是以日產於 2010 年在日本開賣的電動車「Leaf」的車台、技術為根基,由日產與東風日產所攜手研發的車款,而日產也將成為第一家進軍中國電動車市場的日系車廠。   Venucia e30 初期將在北京、上海、廣州、深圳、大連、武漢、天津、鄭州和杭洲等 9 個都市販售,並計劃在 2015 年將販售區域擴及至中國全國。   據日本媒體共同通信指出,Venucia e30 約 4 小時可充飽電、充飽電狀態下的行駛距離為 175km;Venucia e30 將在廣州生產、2018 年銷售目標為 5 萬台。     (圖片來源:)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

分類
發燒車訊

Jmeter系列(31)- 獲取並使用 JDBC Request 返回的數據

如果你想從頭學習Jmeter,可以看看這個系列的文章哦

https://www.cnblogs.com/poloyy/category/1746599.html

 

前言

  • Jmeter 使用 JDBC Request 獲取數據庫中數據,很多人都會用,因為測試中,有時候需要大量的用戶進行登錄,然後獲取數據庫中真實的數據用於測試
  • 前面也詳細講到 JDBC Request 的具體使用,一般是通過 Variable names 和 Result variable name 來獲取返回的數據
  • 這篇文章主要講的就是把 Variable names 和 Result variable name 獲取到的數據提取出來,給到 HTTP 請求使用

 

Variable names + Foreach控制器

線程組結構樹

 

JDBC Request

 

調試取樣器運行結果

有 100 條記錄

 

ForEach控制器

 

循環運行的結果( mobile:${mobile} )

 

Variable names + 循環控制器

和上面的栗子只是換了個控制器而已,沒太大變化

線程組結構樹

 

循環控制器

填寫 100,是代表循環100次

 

計數器

從 1 開始,遞增加到 100為止,每次遞增 1

  • 初始值=1
  • 每次增加 1
  • 最大的值=100(包含)
  • 新變量 num

 

循環控制器內的 Debug Sampler

 ${__V()} 是關聯函數,後面講到

 

循環運行的結果( mobile:${mobile} )

 

Result variable name + Foreach控制器

線程組結構樹

 

JDBC Request

 

正則提取器

 

重點

Applu to 選中 Jmeter Variable Name to use,因為要從 Jmeter Variables 中拿到 result_mobile 變量進行提取

 

調試取樣器運行結果

正則提取后的值是不是跟上面 Variable names 獲取的值列表很像,是的!然後再結合 ForEach控制器就好啦

 

ForEach控制器

變量前綴是正則提取器里的引用名稱

 

循環運行的結果( mobile:${mobile} )

 

Result variable name + 循環控制器

和上面的栗子只是換了個控制器而已,沒太大變化

線程組結構樹

 

循環控制器

填寫 100,是代表循環100次

 

計數器

 

用戶參數

重點一

  •  ${__BeanShell(vars.getObject(“result_mobile”).get(${num}).get(“mobile”))} 
  •  ${__BeanShell()} :執行BeanShell腳本,一般比較短的腳本可以用此方法來寫,後面會再詳細講解這個函數

重點二

  •  vars.getObject(“result_mobile”).get(${num}).get(“mobile”) 
  • result_mobile:是一個數組,即 JDBC Request 里的 Result variable name,每個元素的格式都是 {mobile=158000480001} 
  • ${num}:上面計數器的值,每次遞增 1,這裡是數組下標的意思
  • 總結:獲取 result_mobile 數組,每次取數組中第 num 個元素,從元素中取 mobile 鍵的值【這是固定寫法,只改Object 名、鍵名就行了】

 

循環運行的結果( mobile:${user_mobile} )

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

分類
發燒車訊

深入理解JVM(③)虛擬機的類加載時機

前言

Java虛擬機把描述類的數據從Class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這個過程被稱為虛擬機的類加載機制。

類加載的時機

一個類型從被加載到虛擬機內存中開始,到卸載除內存為止,它的生命周期將會經歷加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和 卸載(Unloading)、七個階段,其中驗證、準備、解析三個部分統稱為連接(Linking)。
類的生命周期如下圖:

其實加載、驗證、準備、初始化和卸載這五個階段的順序是確定的,類型的加載過程必須按照這種順序按部就班地開始,而解析階段則不一定:它在某些情況下可以在初始化階段之後再開始,這是為了支持Java語音的運行時綁定特性(也稱為動態綁定或晚期綁定)。
在什麼情況下需要開始類加載過程的第一個階段“加載”,《Java虛擬機規則》中並沒有進行強制約束,但是對於初始化階段《Java虛擬機規範》則是嚴格規定了有且只有以下六種情況必須立即對類進行“初始化”。

  1. 遇到newgetstaticputstaticinvokestatic這四條字節碼指令時,如果類型沒有進行過初始化,則需要先觸發其初始化階段。
    涉及到這四條指令的典型場景有:
  • 使用new關鍵字實例化對的時候。
  • 讀取或設置一個類型的靜態字段(被final修飾、已在編譯期把結果放入常量池的靜態字段除外)的時候。
  • 調用一個類型的靜態方法的時候。
  1. 使用 java.lang.reflect 包的方法對類型進行反射調用的時候,如果類型沒有進行過初始化,則需要先觸發其初始化。
  2. 當初始化類型的時候,如果發現其父類還沒有進行過初始化,則需要先觸發其父類的初始化。
  3. 當虛擬機啟動時,用戶需要指定一個要執行的主類(包含main()方法的那個類),虛擬機會先初始化這個主類。
  4. 當使用JDK7新加入的動態語言支持時,如果一個java.lang.invoke.MethodHandle實例最後的解析結果為REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial四種類型的方法句柄,並且這個方法句柄對應的類沒有進行過初始化,則需要先觸發其初始化。
  5. 當一個接口中定義了JDK8新加入的默認方法(被default關鍵字修飾的接口方法)時,如果這個接口的實現類發生了初始化,那該接口要在其之前被初始化。
    除了以上的這個六種場景外,所有引用類型的方式都不會觸發初始化,稱為被動引用。
    下面來看一下哪些是被動引用:

例子1:

父類

package com.jimoer.classloading;

/**
 * @author jimoer
 * @date Create in 2020/06/24 16:08
 * @description 通過子類引用父類的靜態字段,不會導致子類初始化。
 */
public class FatherClass {

    static {
        System.out.println("FatherClass init!!!!!");
    }

    public static int value = 666;

}

子類

package com.jimoer.classloading;

public class SonClass extends FatherClass{

    static {
        System.out.println("SonClass init!!!");
    }

}

測試類

@Test
public void testInitClass(){
    System.out.println(SonClass.value);
}

運行結果:

FatherClass init!!!!!
666

通過運行結果我們看到,只輸出了“FatherClass init!!!!!”,並沒有輸出“SubClass init!!!”,這是因為對於使用靜態字段,只有直接定義這個字段的類才會被初始化,因此通過子類來引用父類中定義的靜態字段,並不會初始化子類。

例子2:

/**
 * 通過數組定義來引用類,不會觸發此類的初始化
 */
@Test
public void testInitClass2(){
    FatherClass[] fathers = new FatherClass[5];
}

運行結果:未打印任何信息。
通過運行結果我們發現,並沒有打印出 FatherClass init!!!!! ,這說明並沒有觸發Father類的初始化階段。但是這段代碼裏面觸發了另一個名為“[Lcom.jimoer.classloading.FatherClass”的類的初始化階段,它是一個由虛擬機自動生成的、直接繼承與java.lang.Object的子類,創建動作由字節碼newarray觸發。這個類代表了一個元素類型為FatherClass的一維數組,數組中應用的屬性和方法(length屬性和clone()方法)都實現在這個類里。

例子3:

/**
 * @author jimoer
 * 常量在編譯階段會存入調用類的常量池中,
 * 本質上沒有直接引用到定義常量的類,
 * 因此不會觸發定義常量的類的初始化。
 */
public class ConstantClass {
    
    static {
        System.out.println("ConstantClass init !!!");
    }
    
    public static final String CLASS_LOAD = "class load test !!!";
    
}

使用

/**
 * 使用常量
 */
@Test
public void testInitClass3(){
    System.out.println(ConstantClass.CLASS_LOAD);
}

運行結果:

class load test !!!

通過運行結果,我們看到當在使用一個類的常量時,並不會初始化定義了常量的類。這是因為雖然在Java源碼中確實引用了ConstatClass的類的常量CLASS_LOAD,但其實在編譯階段通過常量傳播優化,已經將此常量的值“class load test !!!”直接存儲在使用常量的類中的常量池中了,所以在使用ConstantClass.CLASS_LOAD時候,實際上都被轉化為在使用類自身的常量池的引用了。

接口也是有初始化過程的,上面的代碼都是用靜態語句塊“static {}”來輸出初始化信息的,而接口中不能使用static{}語句塊,但編譯器仍然會為接口生成“ ()”類構造器,用於初始化接口中所定義的成員變量。
還有一點接口與類不同,當一個類在初始化時,要求其父類全部都已經初始化過了,但是在一個接口初始化時,並不要求其父接口全部都完成了初始化,只有在真正使用到父接口的時候(例如引用接口中的常量)才會初始化。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

分類
發燒車訊

厄瓜多總統與原住民領袖達協議 化解反撙節示威

摘錄自2019年10月14日中央社報導

莫雷諾為向國際貨幣基金貸款42億美元而取消燃油補貼後,國內物價迅速飆升,引發長達12天的示威,造成7人喪命。暴力衝突迫使莫雷諾將政府遷移至厄瓜多第2大城瓜亞基爾(Guayaquil),並嚴重影響石油業,能源部暫停超過2/3原油的配送。抗議人士甚至佔領亞馬遜雨林地區的3處石油設施。

厄瓜多總統莫雷諾及原住民領袖瓦爾加斯13日達成協議,終結近2週來反對撙節措施的暴力抗議。政府是為為獲得國際貨幣基金(IMF)數十億美元貸款,而採取這些緊縮措施。

法新社報導,聯合國官員代表宣讀的聯合聲明說,「根據這項協議,厄瓜多各地的群眾動員劃下句點,我們承諾會恢復國內和平」。聲明並表示,政府已撤回取消燃油補貼的命令。臉上塗著油彩、頭上頂著羽毛頭飾的瓦爾加斯證實:「這些適用於我們全國各地的措施已經取消了。」

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

分類
發燒車訊

使用json-server與Mockjs搭建模擬服務

為什麼使用

在項目開發中,常常需要邊寫前端頁面邊寫後端接口,但是後端接口服務往往是滯後於前端開發的,或者是不能及時提供的。出於前端開發的迅速和便捷去考慮,我們可以根據後端接口數據結構去模擬(mock)數據從而實現前端的獨立開發。
JsonServer 主要的作用就是搭建本地的數據接口,創建json文件,便於調試調用
Mockjs 主要的作用就是生成隨機數據,支持生成隨機的文本、数字、布爾值、日期、郵箱、鏈接、圖片、顏色等

如何使用

以下操作需要node.js環境

1.創建文件夾

選擇自己喜歡的位置創建一個文件夾,比如E:/mock

2.安裝json-server

進入E:/mock

npm install json-server -g 

安裝完執行 json-server -h,若安裝成功則會显示選項

Options:
–config, -c Path to config file [default: “json-server.json”]
–port, -p Set port [default: 3000]
–host, -H Set host [default: “localhost”]
–watch, -w Watch file(s) [boolean]
–routes, -r Path to routes file
–middlewares, -m Paths to middleware files [array]
–static, -s Set static files directory
–read-only, –ro Allow only GET requests [boolean]
–no-cors, –nc Disable Cross-Origin Resource Sharing [boolean]
–no-gzip, –ng Disable GZIP Content-Encoding [boolean]
–snapshots, -S Set snapshots directory [default: “.”]
–delay, -d Add delay to responses (ms)
–id, -i Set database id property (e.g. _id) [default: “id”]
–foreignKeySuffix, –fks Set foreign key suffix (e.g. _id as in post_id)
[default: “Id”]
–quiet, -q Suppress log messages from output [boolean]
–help, -h Show help [boolean]
–version, -v Show version number [boolean]

3.使用json-server
  • 創建json文件,如db.json,文件內容如下
{ "posts": [ { "id": 1, "title": "json-server", "author": "typicode" } ], "comments": [ { "id": 1, "body": "some comment", "postId": 1 } ], "profile": { "name": "typicode" } } 
  • 啟動json-server,cmd執行
json-server --watch db.json 

看到如下內容

 

1574216715(1).jpg


則運行成功,直接訪問圖中显示的三個地址可得結果,如


 

1574216903(1).jpg


至此,簡單的json-server服務已經搭建成功了,後續如果有更多需求,如跨域、參數查詢、路由這些,請參考json-server的github

 

4.安裝Mockjs

進入E:/mock

npm install mockjs --save 
5.使用Mockjs
  • 創建js文件,如news.js,文件內容如下
let Mock=require('mockjs'); let Random=Mock.Random; module.exports=()=>{ let data={ news:[] }; let images=[1,2,3].map(x=>Random.image('120x60',Random.color(),Random.word(2,6))); for(let i=1;i<=100;i++){ let content=Random.cparagraph(0,10); data.news.push({ id:i, title:Random.cword(8,20), desc:content.substr(0,40), tag:Random.cword(2,6), views:Random.integer(100,5000), images:images.slice(0,Random.integer(1,3)) }) } return data } 
  • 啟動json-server,cmd執行
json-server --watch news.js 

訪問結果(部分)


 
 

完成了以上的搭建與驗證過程后,你就可以開始使用json-server與Mockjs來繼續構建模擬服務器了,來滿足自己的各種需要

Tips:

1、也可以使用json-server db.json ,使用“json-server –watch db.json”命令可以實時監測db.json的變化;如果沒有 — watch 命令,即使db.json已經發生了改變,重新發請求,仍然會返回原先的mock data,返回狀態碼304,認為沒有變化。

2、同時,我們可以發送 POST、PUT、PATCH和DELETE請求,相應的結果會通過lowdb自動保存到db.json。關於POST、PUT等相關請求的發送。

3、我們的request body應該是一個json對象,比如{“name”:”Lynn”};

4、POST、PUT、PATCH請求頭中要包含Content-Type: application/json;

5、id的值是自動生成且不易變的。PUT請求和PATCH請求中自帶的id會被忽略。

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

新北清潔公司,居家、辦公、裝潢細清專業服務

※別再煩惱如何寫文案,掌握八大原則!

※教你寫出一流的銷售文案?

※超省錢租車方案

分類
發燒車訊

springboot_自動配置原理

目錄

  • 1.1 @SpringBootApplication
  • 2.1 @EnableAutoConfiguration
    • 2.1.1 @AutoConfigurationPackage
    • 2.1.2 @Import({Registrar.class})
  • 3.1 以HttpEncodingAutoConfiguration為例

springboot啥都不難,總所周知spring全家桶系列難就難在理解源碼。。。。。。。

今天結合網上資料,自己總結了一下springboot的自動配置原理。

我現在使用的springboot版本為2.3.1.不同版本的springboot在源碼上有差別!但大體一致。

管他三七二十一先打個斷點再說:

1.1 @SpringBootApplication

這個註解點進去我們可以看到:

這裏面主要關注兩個東西:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
    第一個註解點進去:

    可以看到這個@SpringBootConfiguration本質就是一個@Configuration,標註在某個類上,表示這是一個Spring Boot的配置類。
    第二個註解@EnableAutoConfiguration: 開啟自動配置類,SpringBoot的精華所在。(最重要的就是這個註解)

2.1 @EnableAutoConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

兩個比較重要的註解:

  • @AutoConfigurationPackage:自動配置包。
  • @Import({AutoConfigurationImportSelector.class}):導入自動配置的組件。

2.1.1 @AutoConfigurationPackage

點進去瞅瞅:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};
}

發現這裡有導入Regitstrar類:

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
        Registrar() {
        }

        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
        }

        public Set<Object> determineImports(AnnotationMetadata metadata) {
            return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
        }
    }

new PackageImport(metadata).getPackageName(),它其實返回了當前主程序類的 **同級以及子級 ** 的包組件。

什麼意思呢?

我們來看這樣一個目錄:

bean1和我們的springboot啟動類位於同一個包下,二bean2不是位於我們啟動類的同級目錄或者子級目錄,那麼我們啟動的時候bean2是不會被加載到的!所以你項目的一切需要加入容器的類必須放在啟動類的同級包下或者它的子級目錄中。

2.1.2 @Import({Registrar.class})

AutoConfigurationImportSelector有一個方法為:selectImports。

public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

它首先回去檢查是否開啟了自動配置類,然後才回去加載註解數據 this.getAutoConfigurationEntry(annotationMetadata);
那麼這個annotationMetadata在哪兒?
來看下面一行代碼:

  protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
再點進去我們會發現這一行代碼:
Enumeration urls = classLoader != null ? classLoader.getResources(“META-INF/spring.factories”) : ClassLoader.getSystemResources(“META-INF/spring.factories”);

它其實是去加載 public static final String FACTORIES_RESOURCE_LOCATION = “META-INF/spring.factories”;外部文件。這個外部文件,有很多自動配置的類。如下:

spring.factories文件由一組一組的key=value的形式,其中一個key是EnableAutoConfiguration類的全類名,而它的value是一個xxxxAutoConfiguration的類名的列表,這些類名以逗號分隔。
springboot項目啟動時,@SpringBootApplication用在啟動類在SpringApplication.run(…)的內部就會執行selectImports()方法,找到所有JavaConfig自動配置類的全限定名對應的class,然後將所有自動配置類加載到Spring容器中。

3.1 以HttpEncodingAutoConfiguration為例

@Configuration(
    proxyBeanMethods = false
)    //表示是一個配置類,可以給容器中添加組件
@EnableConfigurationProperties({ServerProperties.class})// 啟用ConfigurationProperties功能
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(
    prefix = "server.servlet.encoding",
    value = {"enabled"},
    matchIfMissing = true
)

@EnableConfigurationProperties({ServerProperties.class})// 啟用ConfigurationProperties功能
ServerProperties.class:

@ConfigurationProperties(
    prefix = "server",
    ignoreUnknownFields = true
)

@ConditionalOnWebApplication :spring底層@Conditional註解,根據不同的條件進行判斷,如果滿足條件整個配置類才會生效。

總結:
1.springboot會自動加載大量的自動配置類。
2.只要我們要用的組件有,我們就不需要再去配置
3.給容器添加組件的時候。會從properties類中獲取某些屬性。我們就可以在配置文件中指定這些屬性。
xxxxxAutoConfiguration:自動配置類

給容器中添加屬性:
xxxxProperties:封裝配置文件中的相關屬性。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

新北清潔公司,居家、辦公、裝潢細清專業服務

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

分類
發燒車訊

Java 多線程基礎(十一)線程優先級和守護線程

 Java 多線程基礎(十一)線程優先級和守護線程

一、線程優先級

Java 提供了一個線程調度器來監控程序啟動後進去就緒狀態的所有線程。線程調度器通過線程的優先級來決定調度哪些線程執行。一般來說,Java的線程調度器採用時間片輪轉算法使多個線程輪轉獲得CPU的時間片。然而根據實際情況,每個線程的重要程序也不相同,有時候我們想讓一些線程優先執行,那麼我們可以將他的優先級調高一下,這樣它們獲得的時間片會多一些。

多個線程處於就緒狀態時,若這些線程的優先級相同,則線程調度器會按時間片輪轉方式或獨佔方式來分配線程的執行時間。

java 中的線程優先級的範圍是1~10,默認的優先級是5。“高優先級線程”會優先於“低優先級線程”執行。

Java中線程優先級分為三個級別:

  • 低優先級:1~4,其中類變量 Thread.MIN_PRORITY 最低,數值為1;
  • 默認優先級:如果一個線程沒有指定優先級,默認優先級為5,由類變量 Thread.NORM_PRORITY表示;
  • 高優先級:6~10,類變量 Thread.MAX_PRORITY 最高,數值為10。

注意:具有相同優先級的多個線程,若它們都為高優先級Thread.MAX_PRORITY,則每個線程都是獨佔式的,也就是這些線程將被順序執行;若它們優先級不是高優先級,則這些線程將被同時執行,可以說是無序執行。

java 中有兩種線程:用戶線程和守護線程。可以通過 isDaemon() 方法來區別它們:如果返回 false,則說明該線程是“用戶線程”;否則就是“守護線程”。
用戶線程一般用戶執行用戶級任務,而守護線程也就是“後台線程”,一般用來執行後台任務。需要注意的是:Java虛擬機在“用戶線程”都結束後會後退出。

JDK中對用戶線程與守護線程的解釋:

每個線程都有一個優先級。“高優先級線程”會優先於“低優先級線程”執行。每個線程都可以被標記為一個守護進程或非守護進程。在一些運行的主線程中創建新的子線程時,
子線程的優先級被設置為等於“創建它的主線程的優先級”,當且僅當“創建它的主線程是守護線程”時“子線程才會是守護線程”。
當Java虛擬機啟動時,通常有一個單一的非守護線程(該線程通過是通過main()方法啟動)。JVM會一直運行直到下面的任意一個條件發生,JVM就會終止運行:
①、調用了exit()方法,並且exit()有權限被正常執行。 ②、所有的“非守護線程”都死了(即JVM中僅僅只有“守護線程”)。
每一個線程都被標記為“守護線程”或“用戶線程”。當只有守護線程運行時,JVM會自動退出。
 

二、線程優先級示例

public class Demo01 {
    private static Object obj = new Object();
    public static void main(String[] args) {
        
        Thread t1 = new ThreadA("t1");
        Thread t2 = new ThreadA("t2");
        
        t1.setPriority(1); // 設置優先級為1
        t2.setPriority(10);// 設置優先級為10
        
        t1.start();
        t2.start();
    }
}
class ThreadA extends Thread{
    public ThreadA(String name) {
        super(name);
    }
    public void run() {
        for(int i = 0;i < 3;i++)
            System.out.println(Thread.currentThread().getName() + " [ " 
                    + Thread.currentThread().getPriority() + " ] loop " + i);  
    }
}
// 運行結果
t1 [ 1 ] loop 0
t2 [ 10 ] loop 0
t2 [ 10 ] loop 1
t2 [ 10 ] loop 2
t1 [ 1 ] loop 1
t1 [ 1 ] loop 2

說明:

①、主線程main的優先級是5。
②、t1的優先級被設為1,而t2的優先級被設為10。cpu在執行t1和t2的時候,根據時間片輪循調度,所以能夠併發執行。

三、守護線程示例

public class Demo {
    public static void main(String[] args) {

        System.out.println(Thread.currentThread().getName()
                +" [ isDaemon = "+Thread.currentThread().isDaemon()+ " ]");
        Thread t1=new ThreadA("t1");    
        Thread t2=new MyDaemon("t2");    
        t2.setDaemon(true);// 設置t2為守護線程
        t1.start();                        
        t2.start();                        
    }
}
class ThreadA extends Thread{
    public ThreadA(String name) {
        super(name);
    }

    public void run(){
        try {
            for (int i=0; i<5; i++) {
                Thread.sleep(3);
                System.out.println(this.getName() +"[ isDaemon = "+this.isDaemon()+ " ] " + "loop " + i);
            }
        } catch (InterruptedException e) {
        }
    }
};

class MyDaemon extends Thread{
    public MyDaemon(String name) {
        super(name);
    }

    public void run(){
        try {
            for (int i=0; i<10000; i++) {
                Thread.sleep(1);
                System.out.println(this.getName() +"[ isDaemon = " + this.isDaemon() +  " ] " +"loop "+i);
            }
        } catch (InterruptedException e) {
        }
    }
}
// 運行結果
main [ isDaemon = false ]
t2[ isDaemon = true ] loop 0
t2[ isDaemon = true ] loop 1
t2[ isDaemon = true ] loop 2
t1[ isDaemon = false ] loop 0
t2[ isDaemon = true ] loop 3
t2[ isDaemon = true ] loop 4
t1[ isDaemon = false ] loop 1
t2[ isDaemon = true ] loop 5
t2[ isDaemon = true ] loop 6
t2[ isDaemon = true ] loop 7
t1[ isDaemon = false ] loop 2
t2[ isDaemon = true ] loop 8
t2[ isDaemon = true ] loop 9
t2[ isDaemon = true ] loop 10
t1[ isDaemon = false ] loop 3
t2[ isDaemon = true ] loop 11
t2[ isDaemon = true ] loop 12
t2[ isDaemon = true ] loop 13
t2[ isDaemon = true ] loop 14
t1[ isDaemon = false ] loop 4
t2[ isDaemon = true ] loop 15

說明:

①、主線程main是用戶線程,它創建的子線程t1也是用戶線程。
②、t2 是守護線程。在“主線程main”和“子線程t1”(它們都是用戶線程)執行完畢,只剩t2這個守護線程的時候,JVM自動退出。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案