synchronized與lock之間的效能比較
1.關於兩者的實現的比較
A).一般認為synchronized關鍵字的實現是源自於像訊號量之類的執行緒同步機制,涉及到執行緒執行狀態的切換,在高併發狀態下,CPU消耗過多的時間線上程的排程上,從而造成了效能的極大浪費。然而真的如此麼?
執行緒的狀態主要有一下五種,分別是新建狀態,就緒狀態,執行狀態,阻塞狀態,消亡狀態等5種狀態
B).lock實現原理則是依賴於硬體,現代處理器都支援CAS指令,所謂CAS指令簡單的來說Compare And Set,CPU迴圈執行指令直到得到所期望的結果,換句話來說就是當變數真實值不等於當前執行緒呼叫時的值的時候(說明其他執行緒已經將這個值改變),就不會賦予變數新的值
然而,現實情況是當JDK版本高於1.6的時候,synchronized已經被做了CAS的優化:具體是這樣的,當執行到synchronized程式碼塊時,先對物件頭的鎖標誌位用lock cmpxchg的方式設定成“鎖住“狀態,釋放鎖時,在用lock cmpxchg的方式修改物件頭的鎖標誌位為”釋放“狀態,寫操作都立刻寫回主記憶體。JVM會進一步對synchronized時CAS失敗的那些執行緒進行阻塞操作(呼叫作業系統的訊號量)(此段來摘自別處)。也就是先CAS操作,不行的話繼而阻塞執行緒。
除此之外,系統環境,CPU架構,虛擬機器環境都會影響兩者的效能關係。
舉例如下
1).X86_64 cpu i7 4910mq @4.0ghz ,Windows10 64bit,JDK1.8 hotspot 64bit虛擬機器環境
測試程式碼
測試對某Map物件高併發下的讀寫執行緒安全測試
測試對比有synchronized,ReadWriteLock,ConcurrentHashMap,
public class MapTest {
private Map<Integer,String> map = new ConcurrentHashMap<>();
private long starttime;
private AtomicInteger count = new AtomicInteger(t_count);
private final static int t_count = 5000;
private final static int rw_count = 10000;
Runnable readrun = new Runnable() {
@Override
public void run() {
int i = rw_count;
while (i > 0){
map.get(i);
i--;
}
System.out.println("read-mapsize="+map.size());
if(count.decrementAndGet() == 0)
System.out.println("time="+ (System.currentTimeMillis() - starttime +"ms"));
}
};
Runnable writerun = new Runnable() {
@Override
public void run() {
int i = rw_count;
while (i > 0){
map.put(i,i+"");
i--;
}
System.out.println("write-mapsize="+map.size());
if(count.decrementAndGet() == 0)
System.out.println("time="+ (System.currentTimeMillis() - starttime + "ms"));
}
};
public void run(){
starttime = System.currentTimeMillis();
for(int i = 0;i < t_count/2;i ++){
new Thread(writerun).start();
new Thread(readrun).start();
}
}
}
HashMap 用synchronized重寫
public class SyncHashMap extends HashMap{
@Override
public Object get(Object key) {
// TODO Auto-generated method stub
synchronized (this) {
return super.get(key);
}
}
@Override
public synchronized Object put(Object key, Object value) {
// TODO Auto-generated method stub
synchronized (this) {
return super.put(key, value);
}
}
}
用讀寫鎖實現的Map代理類,有些粗糙,沒加try finally
public class SyncMapProxy<K,V> implements Map<K,V>{
private Map<K,V> origin;
private ReadWriteLock lock;
public SyncMapProxy(Map<K, V> origin) {
this.origin = origin;
lock = new ReentrantReadWriteLock();
}
public static <K,V> SyncMapProxy<K,V> SyncMap(Map<K,V> map){
return new SyncMapProxy<K,V>(map);
}
@Override
public void clear() {
lock.writeLock().lock();
origin.clear();
lock.writeLock().unlock();
}
@Override
public boolean containsKey(Object key) {
lock.readLock().lock();
boolean res = origin.containsKey(key);
lock.readLock().unlock();
return res;
}
@Override
public boolean containsValue(Object value) {
lock.readLock().lock();
boolean res = origin.containsKey(value);
lock.readLock().unlock();
return res;
}
@Override
public Set<Entry<K, V>> entrySet() {
lock.readLock().lock();
Set<Entry<K, V>> res = origin.entrySet();
lock.readLock().unlock();
return res;
}
@Override
public V get(Object key) {
lock.readLock().lock();
V res = origin.get(key);
lock.readLock().unlock();
return res;
}
@Override
public boolean isEmpty() {
return origin.isEmpty();
}
@Override
public Set<K> keySet() {
lock.readLock().lock();
Set<K> res = origin.keySet();
lock.readLock().unlock();
return res;
}
@Override
public V put(K key, V value) {
lock.writeLock().lock();
V v = origin.put(key, value);
lock.writeLock().unlock();
return v;
}
@Override
public void putAll(Map<? extends K, ? extends V> map) {
lock.writeLock().lock();
origin.putAll(map);
lock.writeLock().unlock();
}
@Override
public V remove(Object key) {
lock.writeLock().lock();
V v = origin.remove(key);
lock.writeLock().unlock();
return v;
}
@Override
public int size() {
return origin.size();
}
@Override
public Collection<V> values() {
lock.readLock().lock();
Collection<V> res = origin.values();
lock.readLock().unlock();
return res;
}
}
相關推薦
synchronized與lock之間的效能比較
1.關於兩者的實現的比較 A).一般認為synchronized關鍵字的實現是源自於像訊號量之類的執行緒同步機制,涉及到執行緒執行狀態的切換,在高併發狀態下,CPU消耗過多的時間線上程的排程上,從而造成了效能的極大浪費。然而真的如此麼? 執行緒的狀態主要有一下五種,
Synchronized與Lock之間的哪些事兒
Synchronized 一、應用 對於普通同步方法,鎖是當前例項物件; 對於靜態同步方法,鎖是當前類的Class物件; 對於同步程式碼塊,鎖是Synchronized括號裡配置的物件。 二、實現原理 當前一個執行緒試圖訪問同步程式碼塊時,它首先必須
多執行緒的理解思路梳理 + synchronized與Lock 的比較
多執行緒的理解思路梳理 + synchronized與Lock 的比較 理解多執行緒的根本:資源問題與鎖的物件 synchronized的理解 附1:生產者消費者實現程式碼 理解Threa
synchronized與Lock的區別與使用
oca http details detail fps syn blog amp 的區別 https://www.cnblogs.com/benshan/p/3551987.html https://www.cnblogs.com/nsw2018/p/5821738.htm
array_push 與 $arr[]=$value 效能比較分析
本文簡要分析一下php中array_push與$arr[] = $value兩種將元素加入陣列末尾的方法的效能 1. array_push方法 array_push 方法,將一個或多個元素壓入陣列的末尾。array_push() 將array當成一個棧,並將傳入的變數壓入array的末尾。a
Grafana與Kibana之間的比較
我們生活在一個大資料的世界中,即使是一個小型的IT環境也會產生大量資料。一旦組織弄清楚了生成資料的各種資料來源,以及收集,處理和儲存資料的方法,下一步工作的重點就是分析。 分析方法會根據用例、使用的工具以及資料本身而有所不同,但是視覺化資料的步驟,無論是日誌,度量標準還是跟蹤,現在都被視
詳解synchronized與Lock的區別與使用
原文:https://blog.csdn.net/u012403290/article/details/64910926?utm_source=copy 引言: 昨天在學習別人分享的面試經驗時,看到Lock的使用。想起自己在上次面試也遇到了synchronized與Loc
Java多執行緒synchronized與 lock同步及交替列印
synchronized與 lock 區別 1)Lock不是Java語言內建的,synchronized是Java語言的關鍵字。Lock是一個介面,通過這個介面的實現類可以實現同步訪問; 2)採用synchronized不需要手動釋放鎖,當synchronized方法或者sync
Hadoop與Spark之間的比較
原文連結:https://www.cnblogs.com/yjd_hycf_space/p/7681535.html Hadoop框架的主要模組包括如下: Hadoop Common Hadoop分散式檔案系統(HDFS) Hadoop YARN Hadoo
Map與List查詢效能比較
@Test public void mapTest(){ /* * 比較順序查詢和雜湊查詢的效能 */ //建立線性表集合 List<String> list= new ArrayList<String>(); /
指標與引用的效能比較
我們先來看一下傳指標與傳引用的效率方面的對比吧 本質上來說了,傳引用是一個變數的別名而已。並沒有開闢新的空間。而指標了是指向一個空間對應一個空間的地址 好吧,我們分別通過兩者效率,和本質方面看一下兩者之間的區別吧。 -首先看一下兩者的效率 看程式碼 #inclu
properties與yml之間的比較
兩種 als ati try 錯誤 spring 否則 register 並且 在Spring Cloud的配置文件中,發現使用yml與properties兩種後綴的文件: 在application.properties中內容是這樣的: server.port=8801eu
java多執行緒之synchronized與lock、wait與notify
class Res { public String name; public String sex; public Boolean flag = false; public Lock lock = new ReentrantLock(); Condition condition = lock.new
Python基礎入門:List與Tuple、Dict與Set之間的比較
定義方式: L=[1,2,3] T=('a','b',['A','B']) D={key:value,} S=(['a','b','c']) 比較:list與tuple皆為有序,dict與set為無序 因此dict與set不能通過下標序號呼叫,沒有append(),ins
ArrayList與LinkedList、TreeSet與HashSet、HashMap與LinkedHashMap之間的比較
前言:人類一思考,上帝就發笑 之前ArrayList與LinkedList、TreeSet與HashSet、HashMap與LinkedHashMap之間都比較茫然,下面我針對這 幾個類具體類來進行比較,首先我們上一張圖 在上面的比較中,我們針對相同顏色的倆者分別來進行
docker與虛擬機器效能比較
概要 docker是近年來新興的虛擬化工具,它可以和虛擬機器一樣實現資源和系統環境的隔離。本文將主要根據IBM發表的研究報告,論述docker與傳統虛擬化方式的不同之處,並比較物理機、docker容器、虛擬機器三者的效能差異及差異產生的原理。
synchronized 與Lock類
關於同步,以前如果碰到了多執行緒的問題,那麼首先想到的是synchronized 關鍵字,給方法,或者程式碼塊加上synchronized,但是synchronized也有不少缺點,比如它釋放鎖只有兩個條件:1.程式正常結束,鎖被釋放2.程式發生異常,鎖被釋放。除了
synchronized與Lock有什麼異同
Java語言提供了兩種鎖機制來實現對某個共享資源的同步:synchronized和Lock.其中synchronized使用Object物件本身的nofify、wait、nofityAll排程機制,而Lock可以使用Condition進行執行緒之間的排程,完成synchro
原生Servlet與Spring Controller效能比較
在實際專案工作,有同事提出,Java原生的Servlet效能(響應速度與併發數)要比封裝過的Spring Controller高,基於這點,樓主用Apache的ab工具,對兩個簡單的應用做1000併發壓力測試,檢視兩者的響應速度與併發數、平均響應時間等引數。 原生
synchronized與Lock的區別
util 可重入 方法 ted ace ber get ner ack 兩者區別: 1.首先synchronized是java內置關鍵字,在jvm層面,Lock是個java類; 2.synchronized無法判斷是否獲取鎖的狀態,Lock可以判斷是否獲取到鎖; 3.