您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java并發編程怎么理解”,在日常操作中,相信很多人在Java并發編程怎么理解問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java并發編程怎么理解”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
鎖是用來控制多個線程訪問共享資源的方式,一般來說,一個鎖能夠防止多個線程同時訪問共享資源(但是有些鎖可以允許多個線程并發的訪問共享資源,比如讀寫鎖)。
happens-before簡介
從JDK 5開始,Java使用新的JSR-133內存模型(除非特別說明,本文針對的都是JSR-133內存模型)。JSR-133使用happens-before的概念來闡述操作之間的內存可見性。在JMM中,如果一個操作執行的結果需要對另一個操作可見,那么這兩個操作之間必須要存在happens-before關系。這里提到的兩個操作既可以是在一個線程之內,也可以是在不同線程之間
·程序順序規則:一個線程中的每個操作,happens-before于該線程中的任意后續操作。
·監視器鎖規則:對一個鎖的解鎖,happens-before于隨后對這個鎖的加鎖。
·volatile變量規則:對一個volatile域的寫,happens-before于任意后續對這個volatile域的讀。
·傳遞性:如果A happens-before B,且B happens-before C,那么A happens-before C。
注意 兩個操作之間具有happens-before關系,并不意味著前一個操作必須要在后一個操作之前執行!happens-before僅僅要求前一個操作(執行的結果)對后一個操作可見,且前一個操作按順序排在第二個操作之前(the first is visible to and ordered before the second)。
3.2 重排序
重排序是指編譯器和處理器為了優化程序性能而對指令序列進行重新排序的一種手段。
3.2.1 數據依賴性
如果兩個操作訪問同一個變量,且這兩個操作中有一個為寫操作,此時這兩個操作之間
就存在數據依賴性
as-if-serial語義
as-if-serial語義的意思是:不管怎么重排序(編譯器和處理器為了提高并行度),(單線程)
程序的執行結果不能被改變
順序一致性內存模型
其實就是線程所見都是單一的執行順序,i++就是編譯指令為4步的非原子操作,執行順序可變
數據通過總線在處理器和內存之間傳遞。每次處理器和內存之間的數據傳遞都是通過一系列步驟來完成的,這一系列步驟稱之為總線事務(Bus Transaction)。
疑問?這個總線與CPU的總線是一個概念嗎?宏觀的作用上差不多
如圖 來自B站柏義
volatile禁止指令重排是因為LoadStore導致的不能重排
對公平鎖和非公平鎖的內存語義做個總結。
·公平鎖和非公平鎖釋放時,最后都要寫一個volatile變量state。
·公平鎖獲取時,首先會去讀volatile變量。
·非公平鎖獲取時,首先會用CAS更新volatile變量,這個操作同時具有volatile讀和volatile寫的內存語義。
線程的優先級
Deamon線程(美[?di?m?n])
Daemon線程是一種支持型線程,因為它主要被用作程序中后臺調度以及支持性工作。這意味著,當一個Java虛擬機中不存在非Daemon線程的時候,Java虛擬機將會退出。可以通過調用Thread.setDaemon(true)將線程設置為Daemon線程。
1.當主線程退出時,守候子線程會執行完畢嗎?
不一定執行
ti.setDaemon(true);
守候線程執行依賴于執行時間
理解中斷
Thread.interrupt() 設置狀態
isInterrupted() 判斷 返回Boolean
interrupted 即判斷又清除
中斷可以理解為線程的一個標識位屬性,它表示一個運行中的線程是否被其他線程進行了中斷操作。中斷好比其他線程對該線程打了個招呼,其他線程通過調用該線程的interrupt()方法對其進行中斷操作。
線程通過檢查自身是否被中斷來進行響應,線程通過方法isInterrupted()來進行判斷是否被中斷,也可以調用靜態方法Thread.interrupted()對當前線程的中斷標識位進行復位.
線程池技術及其實例
ThreadPoolExecutor源碼
// 執行一個Job,這個Job需要實現Runnablepublic void execute(Runnable command) {} // 關閉線程池public void shutdown() {}處理正在等待的任務,并返回任務列表public List<Runnable> shutdownNow() {}//1)菜用循環CAS操作來將線程數加1;2)新建一個線程并啟用。private boolean addWorker(Runnable firstTask, boolean core) {}//獲取線程池數量public int getPoolSize() {}
到此,關于“Java并發編程怎么理解”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。