更新時間:2019-08-18 09:00:00 來源:動力節點 瀏覽2987次
實現多線程方式有三種:
1、繼承Thread 復寫run方法 無返回值
2、實現Runnable接口復寫run方法,調用thread類的start開啟 無返回值
3、實現callable(指定泛型類)接口實現call方法,創建FutureTask類傳入callable實例,創建thread類傳入futureTask實例調用start方法開啟 有返回值
Thread與runnable關系
發現在多線程實現過程中有三種做法,thread類 runnable接口,從代碼結構本身來講使用runnable是最方便的,因為其可以避免單繼承的局限,用時也可以更好的進行功能的擴充。
thread類是runnable接口的字類,thread類子類實際復寫的是runnable接口的run方法,
runnable與callable的區別?
1、runnable是JDK1.0的時候提出的多線程實現接口,而callable是JDK1.5之后提出的。
2、Runnable接口之中提供一個run方法,沒有返回值。
callable接口提供call方法,可以有返回值
想要實現多線程啟動,使用thread的start方法 從古不變
多線程狀態:
對于多線程開發而言,編寫程序的過程之中總是按照,定義線程主體類,而后通過thread類進行調用start,線程就已經開始運行了,因為整體的線程處理有自己的一套運行的狀態:
創建-start開啟-就緒-阻塞-運行狀態-終止。
1、任何一個線程的對象都應該使用thread類進行封裝,所以線程的啟動使用的是start,進入到就緒狀態并沒有執行,
2、進入到就緒狀態后,就需要等待進行資源調度,當某一個程序調度成功后則進度到運行狀態run方法,但是所有的線程不可能一致持續執行下去,中間需要產生一些暫停的狀態,列入:某線程執行一段時間之后就需要讓出資源,而后這個線程就進入阻塞狀態,隨后重新回到就緒狀態
3、當run方法執行完畢后,實際上該線程的主要任務也就結束了,那么此時就進入到停止狀態
start準備執行--》就緒狀態--》運行狀態-》結束
多線程的主要操作方法都在thread類中定義的
線程的命名與的取:
多線程的運行狀態是不確定的,那么在程序的開發之中為了可以獲取到一些只能夠依靠線程的名字來進行操作
所以線程的名字是一個只管蟲咬的概念,這樣在thread類中就提供線程名稱的處理方式,構造方法傳遞名字,設置名字的方法,獲取名字的方法。
對于線程對象的獲取,是不可能依靠一個this來完成的,因為線程的狀態不可控制,但是有一點可以明確,所有的線程對象一點要執行run方法,那么這個時候我們可以考慮獲取當前線程,在thread里面提供獲取當前線程的方法,
線程休眠:
如果說現在希望某線程可以暫緩執行一次,那么久可以使用休眠處理,在thread類中定義的休眠方法如下,
sleep方法
休眠有可能被打斷,一定要處理
休眠時間一到程序會立即恢復執行
休眠的主要特點是可以自動實現線程的喚醒,以繼續進行后續的處理,但是需要注意的是,如果現在有多個線程對象,那么休眠也有先后順序的
此時產生五個線程對象,并且這五個現場對象執行的方法體是相同的,此時從我們程序執行的感覺來講好像是若干個線程一起進行休眠后,又一起喚醒執行,其實不是,線程是隨機搶占Cpu資源,誰先搶到誰先執行。
線程中斷:
在之前發現線程的休眠里面提供有一個中斷異常,實際上久證明線程的休眠是可以被打斷的,而這種打斷肯定是由其他線程完成的。
在這個thread類里面提供又中斷執行的處理方法
1、isInterrupted 是否被中斷
2、interrupt 中斷線程
所有正在執行的線程都是可以中斷的,中斷線程必須進行異常處理
線程的同步與死鎖:
在多線程的處理之中,可以利用runnable描述多線程操作的資源,而thread描述每一個線程對象,于是當多個線程訪問同一資源的時候如果處理不當就會產生數據的錯誤操作。
方法同步關鍵字 :synchronized 同步代碼塊,同步方法兩種實現方式
線程的強制執行:
所謂的線程的強制執行指的是當滿足某些條件后,某一個線程對象講可以一致獨占資源,一直到該線程的程序執行結束,
線程禮讓:
線程的禮讓指先講線程的執行權讓給別的線程先執行,讓出執行權 方yield方法
禮讓執行的時候,每次都會禮讓當前資源
線程優先級:
從理論上來講線程的優先級越高最先搶到CPU執行權的幾率越高,在thread類里賣弄針對優先級有兩種處理方式
1、設置優先級
2、獲取優先級
在進行優先級定義的時候都是通過int類型的數字來完成的,而對于此數字的選擇在thread類里面久定義號了常量
最高優先級MAX_PRIORITY 10
中級 NORM 5
低級 MAIN 1
所有線程默認優先級是中級
線程同步:
經過分析之后已經可以確認同步問題鎖產生的主要問題,那么下面就需要進行同步問題的解決,但是解決同步問題的關鍵是鎖。
指的是當某一個線程執行操作的時候,其他線程只能在外面等待。
如果要想程序之中實現這把鎖的功能,需要使用關鍵字synchronized關鍵字來實現,同步代碼塊,在同步代碼塊的操作里面代碼只允許一個線程執行,
1、利用同步代碼塊處理:
一般要進行永不對象處理的時候采用當前對象this進行同步
加入同步處理之后,程序的整體性能能下降了,同步實際上會造成性能的降低
2、利用同步方法解決,只需要在方法定義上使用synchronization關鍵字修飾即可
在Java原生類庫的時候會發現,系統中許多的類上使用的同步處理采用的都是同步方法,但是千萬記住同步會造成性能下降
死鎖的概念:
死鎖是在進行多線程同步處理之中有可能產生的一種問題。
所謂的死鎖指的是若干個線程彼此互相等待的狀態。
在多線程開發過程之中最為著名的案例就是生產者與消費者的操作,操作流程如下
1、生產者負責內容的生產
2、每當生產者生產完成一項完整的內容之后消費者要從這里取走內容
3、如果生產者沒有生產完成則消費者需要等待他生產完成才能消費,如果消費者還沒有對內容進行消費,生產者需要等待消費者 消費完成之后在進行生產
解決數據同步問題:
如果要解決問題,首先解決的就是數據同步的處理問題,如果要想解決數據同步最簡單的方式就是同步代碼塊或者同步方法。
但是同步不能解決數據重復問題,只能保證執行順序是一個一個的執行并不會并發處理
解決方案是線程等待與喚醒機制
如果說現在想要解決生產者與消費者的問題,那么最好的解決方案就是使用等待與喚醒機制,而對于等待與喚醒機制主要依賴的是object類的方法處理
方法1:wait 等待
方法2: notify 喚醒
方法3:notifyAll 喚醒全部
優雅的停止線程:
在多線程操作之中如果要啟動多線程肯定是使用thread類的start方法,而如果對于多線程需要進行停止處理,thread類原本提供有stop方法,但是stop方法在1.2的時候已經被廢除了,也不將建議在代碼中使用stop方法。
stop destroysuspend resume這些方法1.2都被廢除了 不建議使用
想要實現多線程停止需要通過一種柔和的方式進行處理,自定義屬性進行判斷修改
線程守護:
現在假設有一個人并且這個人有一個保鏢,這個保鏢一定是在這個人活著的時候進行守護的,如果這個人已經死了額,保鏢也就沒有作用了,
所以在多線程里面進行守護線程的定義,也就是說如果現在主線程的程序或者其他線程還在執行的時候,那么外面的守護線程就一直存在,并且允許在后臺狀態,
setDaemon true 就是設置守護線程方法。
isDaemon 是否是守護線程
可以發現所有的守護線程都是圍繞用戶線程執行的,如果用戶線程執行完畢,守護線程也就消失了,在JVM里面最大的守護線程就是GC線程,程序執行中GC線程會一直存在,如果程序執行完畢,GC線程也就消失
volatile直接內存操作:
面試題:請解釋volatile與synchronized的區別?
volatile主要在屬性上使用,而synchronized是在代碼塊與方法上使用的
volatile無法描述同步處理,它只是一種直接內存的處理,避免了副本的操作,而synchronized是實現同步操作的
volatile它可以更快的表示變量的修改和處理
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習