JVM第五部分 高效并发
java 內存模型與線程
硬件內存模型
?
java內存模型
主內存vs工作內存
所有變量都在主內存(虛擬機內存的一部分),每條線程都有自己的工作內存,線程所有用到的變量都必須從主內存拷貝出來(不能直接讀寫主內存變量)
工作內存如何與主內存交互?
8種內存操作:(lock、uncock) (read、load) (use、assign) (store、write)配對出現
volatile關鍵字
兩種特性:1.變量可見性(共享性,自己看法)2.禁止指令重排
可見性:更改變量,虛擬機主內存刷新后所有線程可見
指令重排:volatile boolean flag=false;
…………(其他java語句)
flag=true;
重排后f,lag初始化后立馬為true;但volatile 修飾后不會
使用volatile前提條件:
1.運算結果不依賴當前值,或者能夠確保只有單一線程修改變量
2.變量不需要其他狀態變量參與
volatile關鍵字在寫操作耗時,但是也比鎖的總開銷小
線程實現
三種方式:內核線程,用戶級線程,用戶加輕量級進程混合實現
內核線程狀態轉換開銷大,程序一般使用的是內核線程的高級接口——輕量級進程(LWP)
java線程調度
兩種方式:協同式線程調度(效果極差),搶占式線程調度(協同分配時間)
java線程定義優先級,實現給某些進程更多時間,但是不太靠譜,java優先級與系統優先級不是一一對應
狀態轉換
新建-運行-等待-阻塞-結束
java線程安全與鎖優化
5類
1.不可變
final關鍵字修飾的對象、屬性
2.絕對線程安全
api實現同步,但是絕對線程安全不是絕對的線程安全
vector get() remove()方法,get(i)同時remove(i),那么,拋出數組越界異常
3.線程相對安全
我們通常說的線程安全,需要保證對象單獨的操作是線程安全的,我們調用時不需要額外做保證。但是,特定順序的連續調用,也可能額外同步手段
4.線程兼容
對象本身不是線程安全,調用端正確使用同步手段保證
5.線程對立
不可能實現多線程安全的代碼
線程安全實現方法?
1.互斥同步(悲觀策略)
互斥方法:臨界區 互斥量 信號量
synchronized
2.非阻塞同步(樂觀策略)
3.無同步方案
a.可重入代碼(返回結果可預測)
?b.線程本地儲存
鎖優化
1.自旋鎖與自適應自旋
無法獲取鎖時,自旋等待一直請求,短時間內可以獲得很好收益(避免線程切換開銷),自旋次數到達限定次數后,掛起。
2.鎖消除
檢測到不存在競爭,消除鎖(不存在競爭還加鎖?api中也有很多鎖,比如stringBUffer.append()),stringBUffer.append(s1),stringBUffer.append(s2),stringBUffer.append(s3),三個鎖,可以被消除
3.鎖粗化
同一個對象反復加鎖,那么加鎖同步范圍擴大,還是上面的stringBUffer.append()),stringBUffer.append(s1),stringBUffer.append(s2),stringBUffer.append(s3),鎖粗化后只剩第一個鎖。
4.輕量級鎖(看書)
5.偏向鎖(看書)
?
轉載于:https://www.cnblogs.com/zhijianhu/p/8811262.html
總結
以上是生活随笔為你收集整理的JVM第五部分 高效并发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win10修改EFI分区文件
- 下一篇: 身份证号前缀与区域对照表