線程
1.線程的相關(guān)概念
2.線程的創(chuàng)建和啟動 ★
3.線程的停止
4.線程的常見方法(Thread)
5.線程的生命周期 ★
6.線程的同步
7.線程的通信
線程的相關(guān)概念
概念
程序:為了讓計算機完成某個特定的功能,編寫的一系列有序指令的集合。
實則是一段靜止的代碼段
進程:正在運行的程序,它有自己的生命周期
線程:輕量級的進程。一個進程可以劃分為若干個執(zhí)行單位,每個執(zhí)行單位可以看做是一個線程
一個進程可以包含多個線程
比如:正在運行的qq
它也有自己的生命周期
單線程:一個進程中,在同一個時刻,只能運行一個線程,必須等待該線程執(zhí)行結(jié)束,其他線程才能開始執(zhí)行
多線程:一個進程中,在同一個時刻,可以同時運行多個線程
單核cpu: 僅僅只是貌似 “同時”
多核cpu: 有可能出現(xiàn)真正“同時”
比如:qq 同時打開多個線程,打開qq新聞、打開qq聊天窗口
多線程的好處
1、有效的占用了cpu的空閑時間,從一定程度上提高了效率
2、提高了用戶的體驗性
3、將一個復雜的進程拆分成若干個小的線程,提高代碼的分離性和維護性
線程的創(chuàng)建和啟動
方式一:繼承Thread
定義線程類:
class MyThread extends Thread{
public void run(){
//編寫新線程要執(zhí)行的任務(wù)體
}
}
創(chuàng)建新線程,并啟動
new MyThread().start();
方式二:實現(xiàn)Runnable
定義任務(wù)類:
class MyRunnable implements Runnable{
public void run(){
//編寫新線程的任務(wù)體
}
}
創(chuàng)建新線程,并啟動
new Thread(new MyRunnable()).start();
兩種方式的對比★
1、方式二避免了單繼承的局限性,使用更加靈活
2、方式二更適合處理多線程共享資源的情況
線程的停止
1.stop 已經(jīng)過時
2.Interrupt 只能中斷睡眠、等待這些狀態(tài),會拋出InterruptedException異常,并沒有真正的結(jié)束線程
3.采用通知的方法 ★
步驟1:讓需要停止的線程中添加一個循環(huán)標記,默認值為true
步驟2:讓需要停止的線程中添加一個公共的set方法,用于更新循環(huán)標記
步驟3:需要停止該線程時,調(diào)用set方法即可
線程的常見方法 【了解】
currentThread 獲取當前線程對象 //Thread.currentThread().getName();
setName設(shè)置線程名稱
getName獲取線程名稱
setPriority設(shè)置線程優(yōu)先級1——10
getPriority獲取線程優(yōu)先級
sleep休眠
interrupt中斷休眠狀態(tài)
yield線程的禮讓
join線程的插隊
setDaemon設(shè)置守護線程
線程的生命周期
線程的同步
理解
線程的同步實際上就是線程的安全問題。如果多個線程處理共享資源時,出現(xiàn)了數(shù)據(jù)安全問題,稱為線程的同步問題!
線程的同步如何發(fā)生的?
當多條語句在操作同一個線程共享數(shù)據(jù)時,一個線程對多條語句只執(zhí)行了一部分,還沒有執(zhí)行完,另一個線程參與進來執(zhí)行。導致共享數(shù)據(jù)的錯誤
如何避免線程的同步問題?
對多條操作共享數(shù)據(jù)的語句,只能讓一個線程都執(zhí)行完,在執(zhí)行過程中,其他線程不可以參與執(zhí)行
借鑒:火車廂的洗手間的上鎖的方式
線程的同步的實現(xiàn)方式 ★
對象+synchronized 搭配使用
方式一:同步代碼塊
synchronized(鎖對象){
//需要上鎖的代碼(同步的代碼)
}
方式二:同步方法
public synchronized 返回類型 方法名(參數(shù)列表){
//需要上鎖的代碼(同步的代碼)
}
注意:
普通的同步方法,鎖對象是:this
靜態(tài)的同步方法,鎖對象是:當前類.class
要求:
多個線程使用的鎖對象必須是同一個?。?!
線程的同步前提
1、多線程
2、有共享資源&線程的任務(wù)體中有對共享資源處理語句
使用同步的落地步驟 ★
1、先分析需要上鎖的代碼
2、分析需要同步代碼塊還是同步方法
3、檢測多線程使用的鎖對象是否為同一個?。。?
線程的死鎖
發(fā)生原因:多個線程都需要用到多把鎖,每一個線程都需要對方線程的鎖對象,如果多個線程互不相讓,導致死鎖問題
線程的通信
理解
線程的通信也就是 線程之間的 “交流”,也就是通過一定的方法,實現(xiàn)線程的控制!
相關(guān)的API ★
一、wait
語法:
鎖對象.wait();
特點:
1、讓當前線程等待,直到其他線程調(diào)用了該鎖對象的notify或notifyAll方法為止,否則將一直等待
2、wait的調(diào)用 必須在同步的前提下
3、wait的調(diào)用 會導致鎖的釋放
4、如果等待結(jié)束也就是被喚醒后,則繼續(xù)從斷點處往下執(zhí)行!
二、notify和notifyAll
語法:鎖對象.notify()|notifyAll();
特點:
1、notify:喚醒當前鎖對象下等待的單個線程。優(yōu)先級較高的優(yōu)先喚醒,如果優(yōu)先級一樣,則隨機
notifyall:喚醒當前鎖對象下所有等待的線程
2、notify和notifyAll的調(diào)用,必須在同步的前提下
注意:
wait、notify、notifyAll和當前同步代碼的鎖對象都必須是同一個!否則報異常?。。?!