Java线程之核心概念
2019獨角獸企業重金招聘Python工程師標準>>>
1.線程的三個基本角色
線程是一個執行流程,它不是類,也不是對象。我們先來梳理一下線程的三個基本角色:
Runnable和Thread不是一個概念的東西,一個是任務入口,一個是線程管理員。創建一個線程最佳的辦法應該是先創建一個實現了Runnable接口的類,然后再把它注入Thread對象,而不是直接繼承Thread對象。這樣程序才看起來職責分明。
this thread是指由某個Thread對象管理的那個線程。current thread是指運行時的那個線程。我們平時可能很少注意這兩者的區別,經常弄不清被操作者是this thread還是current thread(操作者總是current thread)。我這里做個總結:
- 鎖操作的對象永遠是current thread;
- Thread的靜態方法操作的對象永遠是current thread;
- Thread的成員方法操作的對象永遠是this thread;
舉一個很經典的例子:interrupt()是一個成員方法,會讓this thread中斷;interrupted()是一個靜態方法,作用是檢測current thread是否是中斷的;?? ?isInterrupted()又是一個成員方法,作用是檢測this thread是否是中斷的。
當然,this thread可以轉化為current thread。通過Thread類的靜態方法currentThread(),就可以得到運行時線程的Thread對象,這個Thread對象調用成員方法的時候,操作的也是current Thread,因為這時this thread和current Thread是同一個線程。Thread.interrupted()和Thread.currentThread().isInterrupted()是等效的。
任何對象都可以是鎖。鎖的作用有兩個:同步和協作。wait()/wait(long timeout)/?? ?wait(long timeout, int nanos)/notify()/notifyAll()都是鎖的方法,如果一個對象沒有被當做鎖,調用這些方法就會報錯。synchronized可以讓一個對象成為一把鎖,起到同步的作用,而鎖的這些方法可以協調需要這把鎖的多個線程。
好了,現在梳理清楚了線程的三個基本角色,以及它們之間的關系。接下來總結一下多線程的兩大用處。
?
2.線程的兩大用處
多線程其實就兩個用處,一是并行,二是并發。并行和并發的區別可以看下圖。并行帶來的好處顯而易見,多一個咖啡機,我們就能早點喝到咖啡。并行就不一定了,排了兩個隊,只有一個咖啡機,在拿咖啡的時候兩隊最前面的兩個人還要搶一下(線程同步開銷),才能喝到咖啡,我們可能會因此更晚喝到咖啡。
但是并發其實好處也很多,比如除了消費者,還有咖啡供應者,假設每個咖啡機消費者一分鐘能消費一杯咖啡,供應者十分鐘才能做好一杯新鮮的咖啡放在咖啡機。那怎么辦呢?那就每個咖啡機要十個以上供應者(算上同步開銷的話),才能滿足消費者的需求。
并行是多個線程在各自狀態環境下運行。并發是多個線程在同一個狀態環境下運行。并發通常需要引入同步機制,維護狀態的一致性。
到底是選擇并行還是并發,關鍵看線程之間需不需要共享狀態數據,如果不需要,就選擇并行。如果需要,就選擇并發,并且想好同步機制。
?
3.線程的同步和協作細節(并發)
然后再看一下,并發線程之間是怎么同步和協作的,直接上圖(這是《圖解Java多線程模式》書中的圖,圖美盜之):
?
?
?
注意:
?
4.線程的狀態
最后,總結一下線程的生命周期:
線程的狀態包括:初始狀態、可執行狀態、執行狀態、等待狀態、阻塞狀態、終止狀態。等待狀態和阻塞狀態有什么區別呢?阻塞是為了同步(遇到敵人的時候),最終由操作系統內核喚醒,等待是為了協作(和朋友合作的時候);最終由其他線程喚醒。這兩種狀態都不占用cpu,執行狀態才占用cpu。
?
5.并發包都有什么
從Java 5開始,引入了并發包。在后續的文章會逐一提到里面的詳細內容。里面的內容都逃不出本文的范疇。無非是圍繞創建、執行、同步、協作、獲取執行結果……這幾個主題進行抽象封裝。讓多線程程序寫起來更輕松而已。
轉載于:https://my.oschina.net/leaforbook/blog/1823980
總結
以上是生活随笔為你收集整理的Java线程之核心概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SSE图像算法优化系列十九:一种局部Ga
- 下一篇: Java集合框架源码解析之ArrayLi