CoreJava 笔记总结-第十二章 并发-1
生活随笔
收集整理的這篇文章主要介紹了
CoreJava 笔记总结-第十二章 并发-1
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
第十二章 并發(fā)
線程
package chapter12_concurrent.threads;public class ThreadsTest {public static final int DELAY = 10;public static final int STEPS = 100;public static final double MAX_AMOUNT = 1000;public static void main(String[] args) {var bank = new Bank(4, 100000);//Runnalbe 是一個(gè)函數(shù)式接口,可以用一個(gè)lambda表達(dá)式創(chuàng)建一個(gè)實(shí)例Runnable task1 = () -> {try {for (int i = 0; i < STEPS; i++) {double amount = MAX_AMOUNT * Math.random();bank.transfer(0, 1, amount);Thread.sleep((long) (DELAY * Math.random()));}} catch (InterruptedException e) {}};Runnable task2 = () -> {try {for (int i = 0; i < STEPS; i++) {double amount = MAX_AMOUNT * Math.random();bank.transfer(2, 3, amount);//休眠制定的毫秒數(shù)Thread.sleep((long) ( DELAY * Math.random()));}} catch (InterruptedException e) {}};//構(gòu)造一個(gè)Thread對象,啟動線程new Thread(task1).start();new Thread(task2).start();} }線程狀態(tài)
- New, Runnable, Blocked, Waiting, Timed waiting, Terminated
分別表示線程的六種狀態(tài): 新建, 可運(yùn)行, 阻塞, 等待, 計(jì)時(shí)等待, 終止
新建線程
- new Thread(r) 新建線程, 但是還沒有開始運(yùn)行
可運(yùn)行線程
- 調(diào)用start方法后線程就屬于可運(yùn)行狀態(tài), 處于runnable可能運(yùn)行也可能沒有運(yùn)行
阻塞和等待進(jìn)程
- 線程處于阻塞和等待狀態(tài)不活動,不運(yùn)行任何代碼,消耗最少資源
- 當(dāng)線程試圖獲取一個(gè)內(nèi)部的對象鎖,而該鎖目前被其他線程占有,該線程就會被阻塞.所有其他線程釋放這個(gè)鎖,并且線程調(diào)度器允許該線程持有這個(gè)鎖,他將變成非阻塞狀態(tài)
- 當(dāng)線程等待另一個(gè)線程通知調(diào)度器出現(xiàn)一個(gè)條件時(shí),這個(gè)線程會進(jìn)入等待狀態(tài)
- 有的方法有超時(shí)參數(shù),調(diào)用這些方法會讓線程進(jìn)入計(jì)時(shí)等待狀態(tài).這一狀態(tài)會一直等待到超時(shí)期滿或者接收到適當(dāng)?shù)耐ㄖ?/li>
終止線程
- run方法正常退出
- 一個(gè)沒有捕獲的異常終止了run方法
線程屬性
中斷線程
- interrupt方法可以用來請求終止一個(gè)線程,程序調(diào)用該方法就會設(shè)置線程中斷狀態(tài)
- 測試是否設(shè)置了中斷狀態(tài):Thread.currentThread()獲得當(dāng)前線程
-
線程被阻塞就無法檢查中斷狀態(tài)
-
當(dāng)在一個(gè)被sleep, wait調(diào)用的阻塞的線程上調(diào)用interrupt方法,那個(gè)阻塞調(diào)用將被一個(gè)InterruptedException異常中斷
-
一般將中斷解釋為一個(gè)中止請求
-
如果循環(huán)調(diào)用了sleep,不要檢測中斷狀態(tài),應(yīng)當(dāng)捕獲InterruptedException
-
interrupted: 靜態(tài)方法, 檢查當(dāng)前線程是否中斷,并且清楚線程中斷狀態(tài)
-
isInterrupted: 實(shí)例方法, 檢查是否有線程被中斷,不改變中斷狀態(tài)
-
不要抑制InterruptedException異常:
-
-
catch子句中調(diào)用Thread.currentThread().interrupt()設(shè)置中斷狀態(tài),調(diào)用者就可以檢查中斷狀態(tài)了
- void mySubTask(){...try{sleep(delay);}catch(InterruptedException e){Thread.currentThread().interrupt()} }
-
更好的是,標(biāo)記方法,去掉try語句塊
- void mySubTask() throw InterruptedException { ... sleep(delay); }
-
守護(hù)線程
- t.setDaemon(true);
- 守護(hù)線程唯一作用就是為其他線程提供服務(wù)
線程名
- 默認(rèn)狀態(tài)下有容易記憶的名字
- 改名:setName(...)
未捕獲異常的處理器
- 線程組ThreadGroup類實(shí)現(xiàn)了Thread.UncaughtExceptionHandler接口,其uncaughtException方法執(zhí)行以下操作:
- 該線程若有父線程那么調(diào)用父線程的uncaughtException方法
- 如果Thread.getDefaultExceptionHandler方法返回一個(gè)非null處理器,調(diào)用該處理器
- 否則,如果Throwable類是ThreadDeath的一個(gè)實(shí)例,什么也不做
- 否則將線程的名字和Throwable棧軌跡輸出到System.err
線程的優(yōu)先級
- setPriority方法提高或者降低任何一個(gè)線程的優(yōu)先級
- MIN_PRIORITY(1), NORM_PRIORITY(5), MAX_PRIORITY(10)
同步
- 競態(tài)條件: 兩個(gè)及以上線程共享對同一組數(shù)據(jù)的存取, 線程相互覆蓋導(dǎo)致對象破壞
- 不同步的操作:
鎖對象
- 兩種機(jī)制可以防止并發(fā)訪問代碼塊: synchronized, ReentrantLock
- 基本結(jié)構(gòu):
- 該結(jié)構(gòu)確保任何時(shí)刻只有一個(gè)線程進(jìn)入臨界區(qū),一旦一個(gè)線程鎖定了鎖對象,其他任何線程無法通過lock語句
- 要把unlock放入finally語句.如果臨界區(qū)代碼異常,鎖必須釋放,否則線程永遠(yuǎn)阻塞
- 每個(gè)bank有自己的ReentrantLock對象,兩個(gè)線程視圖訪問同一個(gè)bank對象,鎖可以用來保證串行化訪問
- 兩個(gè)線程訪問不同的bank對象,每個(gè)線程會得到不同的鎖對象,線程不會阻塞
條件對象
- 下面的Bank類加入了鎖對象, 保護(hù)金額轉(zhuǎn)賬不夠時(shí)候線程覆蓋的情況
- 引入了條件對象, 調(diào)用await方法將當(dāng)前線程暫停,放棄鎖,允許其他線程執(zhí)行
- 另一個(gè)線程完成轉(zhuǎn)賬后調(diào)用signalAll重新激活等待這個(gè)條件的所有線程
- 其中的某個(gè)線程將從await調(diào)用處返回得到這個(gè)鎖,繼續(xù)執(zhí)行之前暫停的地方
總結(jié)
以上是生活随笔為你收集整理的CoreJava 笔记总结-第十二章 并发-1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。