Android筆記(十七)Android多線程問題

參考 https://mp.weixin.qq.com/s/gBZcogHizremZoJRvd8fHQ

線程的幾個方法

  1. run()。非靜態
  2. start()。非靜態
  3. join()。非靜態。如果線程 A 調用了線程 B 的 join() 方法,那線程 A 會進入等待狀態,直到線程 B 運行結束。
  4. currentThread()。靜態
  5. yield()。靜態。降低當前線程優先級,調用該方法就像是是對線程調度器說:“如果其他線程要處理器資源,那就給它們,否則我繼續用”。
  6. sleep()。靜態

線程的生命週期

在這裏插入圖片描述

JVM內存模型

在這裏插入圖片描述
JAVA運行時的數據區域可以包括:
方法區。方法區存放類的信息(包括類的字節碼,類的結構)、常量、靜態變量等。字符串常量池就是在方法區中。
堆區。主要存放數組和對象,包括持久代,年老代,初生代等
虛擬機棧。線程獨佔。存放局部變量表(基礎數據和引用)
本地方法棧。線程獨佔。存放native相關
程序計數器(線程寄存器)。線程獨佔。保存線程執行指令

JAVA內存模型

java內存模型
這幅圖是區分於JVM內存模式。後者是從功能上區分內存模型,前者是從架構考慮,高速cache的存在是爲了加速數據讀寫,而不同線程之間對內存的讀寫就涉及到了多線程併發工作的問題,從而產生了競態這一說法。

線程安全性問題(競態)

  1. 原子性。操作不可分割。其他線程不會參與
  2. 可見性。某一線程改變共享變量後需要同步到其他線程
  3. 有序性。保證操作的有序性。重排序(Reordering)處理器和編譯器是對代碼做的一種優化,它可以在不影響單線程程序正確性的情況下提升程序的性能,但是它會對多線程程序的正確性產生影響,導致線程安全問題。

實現線程安全(鎖)

要實現線程安全就需要保證上面的三點。常見的實現線程安全的辦法是使用鎖和原子類型,而鎖可分爲內部鎖(synchronized)、顯式鎖、讀寫鎖、輕量級鎖(volatile)四種

  • 內部鎖(synchronized)。同步方法或者代碼塊,鎖住特定類和特定對象。因爲使用 synchronized 實現的線程同步是通過監視器(monitor)來實現的,所以內部鎖也叫監視器鎖。不需要手動釋放鎖如(unlock),可以自動解鎖非公平鎖
  • 顯示鎖,實現了Lock接口。可重入,鎖多次;需要手動獲取和釋放,允許調整鎖策略成功公平/非公平鎖。
  • 讀寫鎖
  • volatile 關鍵字
  • 在這裏插入圖片描述
    讀線程執行的加載屏障和寫線程執行的存儲屏障配合在一起,能讓寫線程對 volatile 變量的寫操作對讀線程可見,從而保證了可見性;volatile 能禁止指令重排序,也就是使用 volatile 能保證操作的有序性;在原子性方面,對於 long/double 型變量,volatile 能保證讀寫操作的原子型
    對於非 long/double 型變量,volatile 只能保證寫操作的原子性。

死鎖 4 個必要條件

  • 互斥
  • 佔有且等待
  • 不可搶佔
  • 循環等待
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章