併發與多線程——線程安全

基本概念

併發:在某個時間段內,多任務交替處理的能力。

並行:同時處理多任務的能力。

併發與並行的目標:盡肯能快的執行完所有任務

併發特點:

  1. 併發程序之間有相互制約的關係。

    (1)直接制約:一個程序需要另一個程序的結果。

    (2)間接制約:程序間競爭共享資源。

處理器、緩衝區、磁盤IO等

  1. 併發程序的執行過程是斷斷續續的。

這與CPU的調度算法有關

  1. 併發數設置合理並且CPU擁有足夠處理能力是,併發會提高程序的效率。

(1)在極端情況下,比如單核CPU,在單核的條件下,併發一般比串行效率要低,只要消耗在上下文切換–記憶現場和恢復現場等。
(2)防止阻塞:單核CPU下使用併發,主要是考慮防止阻塞。單核CPU使用單線程,如調用接口遲遲沒有返回,那你的線程就一直阻塞,直到接口返回爲止,但使用多線程就能防止這個問題,就算一個接口調用阻塞了,但並不影響其他線程的執行。

線程安全

  1. 線程狀態

在這裏插入圖片描述

(1) new,新建狀態,線程被創建且未啓動的狀態。

​ 創建線程的三種方式:

​ a. extends Thread

​ b. implement Runnable

​ c. implement Callable

相比第一種,推薦第二種,因爲繼承不符合里氏代換原則;Runnable與Callable的不同點:
第一,call()方法具有返回值,前兩種方式都有缺陷,即在任務執行完成後無法直接獲取執行結果,需要藉助共享變量獲取。
第二,call()可以拋出異常。Runnable只能通過setDefaultUncaughtExceptionHandler()的方式才能在主線程中捕獲到子線程的異常。

(2) runnable,就緒狀態,調用start()之後運行之前的狀態。

start()不能多次調用。

(3) running,運行狀態,run()正在執行的狀態。

時間、異常、鎖、調度等會使線程退出running

(4)blocked,阻塞狀態,以下情況會進入阻塞狀態:

a.同步阻塞:鎖被其他線程佔用。

b.主動阻塞:調用Thread的某些方法,主動讓出CPU執行權,如sleep()、join()等。

c.等待阻塞:wait()。

sleep與wait的相同點:sleep與wait都會使CPU讓出執行權,不同點:sleep不會釋放線程所佔有的鎖,wait會釋放線程所佔有的鎖

(5)dead,終止狀態,run()執行結束或者異常退出後的狀態,此狀態不可逆轉。

  1. 線程安全

    (1)數據單線程內可見。

線程局部變量

(2)只讀對象。

條件:使用final修飾類,避免繼承;使用private final修飾屬性避免修改;沒有任何的更新方法;返回值不能爲可變對象的引用;

(3)線程安全類。

(4)同步與鎖機制。

  1. 併發包

    (1)線程同步類。

主要代表爲CyclicBarrier、CountDownLatch、Semaphore等,逐步淘汰wait和notify同步方式。

(2)併發集合類。

主要代表ConcurrentHashMap(不斷優化,從分段鎖到CAS)、CopyOnWriteArrayList、BlockingQueue等。

(3)線程管理類。

線程池ThreadPoolExecutor

(4)鎖相關類。

Lock,主要代表爲ReentrantLock

《Easy Coding》讀書筆記

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章