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