ConurrentHashMap

LinkedList 線程安全版本

class Node{
	int val;
	Node next;
}
class LinkedList{

	Node head = null;
	void pushFront(int val){}
	void pushBask(int val){}
	
}

1.最簡單的辦法:當前鏈表對象( LinkedList this )
很多時候,線程之間有些是沒有必要互斥的
A 線程在頭插:1. 新建一個節點 2. 修改鏈表的head
B 線程在尾插:1. 新建一個節點 2. 修改鏈表最後一個節點的next
所以需要更細粒度的鎖
在這裏插入圖片描述
使用CAS方法僞代碼:

Node head=this.head;
Node node=new Node(val,head);	
//CAS成功,代表頭插成功,結束
//CAS失敗,表示在這之前已經有其他線程完成頭插,我們重新獲取head再次進行頭插
while(CAS(address,head,node)==false){
	head=this.head;
	node.next=head;
}

使用CAS其實是放棄了強一致性:
A先開始頭插 / B後開始頭插
結果B先被調度,導致B CAS成功
B的節點就先被頭插了

2 . ConturrentHashMap
在這裏插入圖片描述
線程安全的集合類:
Vector / HashTable(不建議使用了)
順序表
不建議使用的原因是:每個方法都會帶着一個synchronized(搶一把大鎖),所以效率低
CopyOnWriteArrayList(因爲是不可變對象)
讀的時候不影響,一旦修改,會立刻賦值一份然後在自己的這份中做修改

List list =Collections.synchronized(new ArrayList() );
list是線程安全的,但是效率不高不建議使用

需要注意 ConcurrentHashMap不支持null作爲key,hashMap是支持null作爲key的。

提問:
現在已知A類是線程安全的,B類只使用了A類,問B類是線程安全的嗎?

class MyClass{
	private ConcurrentHashMap=...;
public add(){
   if(map.containsKey(key)){
	  map.deleteKey(key);
       }
   }
}

這個不是線程安全的:
如果A線程發現map中存在key正準備刪除,此時CPU發生調度,B線程進入,並且完成了delete操作。
現在B線程調下去,A線程再次進入就會發生刪除失敗。所以不是線程安全的。
所以線程安全是不會傳染的。

串加工廠模式:

沒有工廠的時候:
Person p=new Person();
有了工廠
Person p=PersonFactory.build();
工廠的工廠
PersonFactory pf= FactoryFactory.build();
Person p=pf.build();

作用:
加入有5000萬行代碼
new Person()寫了800萬次,分佈在各個地方。
有一天,需要修改一下new Person()的方式。則需要全部修改

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