測試Java的synchronize和ReentrantLock在單線程下的效率

來源:互聯網
上載者:User

ReentrantLock 在多線程情況下要遠勝synchronize,這點沒有疑問。

最近要寫個程式,有個變數是有多數情況下是一個線程讀寫,有少數情況下是多個線程並發讀寫。所以要測試下ReentrantLock 在單線程下和synchronize的效率對比。

在測試的過程中發現一個有意思的現象。

測試代碼見後面。

測試代碼1結果:

noLockTime: 0:00:00.004
noLockTime: 0:00:00.006
noLockTime: 0:00:00.000
syncTime: 0:00:02.902
syncTime: 0:00:02.902
syncTime: 0:00:02.886
ReentrantTime: 0:00:05.012
ReentrantTime: 0:00:05.007
ReentrantTime: 0:00:04.270

則開始看到這個測試結果,覺得相當奇怪,ReentrantLock居然比synchronize要慢這麼多。

但是後來再仔細研究測試結果,發現原來是jvm把測試代碼最佳化掉了!觀察noLockTime的時間,差不多是0!

於是加上total的統計代碼,得到以下的測試結果:

加上total統計的測試代碼結果:

noLockTime: 0:00:03.786
total:1078760960
noLockTime: 0:00:03.774
total:1078760960
noLockTime: 0:00:03.428
total:1078760960
syncTime: 0:00:05.553
total:1078760960
syncTime: 0:00:05.555
total:1078760960
syncTime: 0:00:04.826
total:1078760960
ReentrantTime: 0:00:05.451
total:1078760960
ReentrantTime: 0:00:05.424
total:1078760960
ReentrantTime: 0:00:04.493
total:1078760960

這個結果算是正常的結果了。

總結:

  1. 以前一直聽說JVM可以在運行時最佳化代碼,果然是相當的牛B的功能,直接在運行時把無用的代碼全最佳化掉了。
  2. 測試程式要注意防止jvm等的最佳化
  3. ReentrantLock和synchronize在單線程下效率基本一樣(從實現原理來看,在單線程情況下,都是一個比較指令即可)
  4. 在單線程下,ReentrantLock和synchronize的效率是非常高的,一次調用約10e-11秒。

測試代碼1:

import java.util.concurrent.locks.ReentrantLock;import org.apache.commons.lang3.time.StopWatch;public class XXX {static ReentrantLock lock = new ReentrantLock(false);static int size = 100;static int count = 100000000;static StopWatch watch = new StopWatch();public static void main(String[] args) {noLockTime();noLockTime();noLockTime();syncTime();syncTime();syncTime();ReentrantTime();ReentrantTime();ReentrantTime();}static void noLockTime(){//int total = 0;watch.reset();watch.start();for(int i = 0; i < count; ++i){testNotLock();//total += testNotLock();}watch.stop();System.out.println("noLockTime: " + watch);//System.out.println("total:" + total);}static void syncTime(){//int total = 0;watch.reset();watch.start();for(int i = 0; i < count; ++i){testSync();//total += testSync();}watch.stop();System.out.println("syncTime: " + watch);//System.out.println("total:" + total);}static void ReentrantTime(){//int total = 0;watch.reset();watch.start();for(int i = 0; i < count; ++i){testReentrantLock();//total += testReentrantLock();}watch.stop();System.out.println("ReentrantTime: " + watch);//System.out.println("total:" + total);}static int testNotLock(){int sum = 0;for(int i = 0; i < size; ++i){sum += i;}return sum;}static synchronized int testSync(){int sum = 0;for(int i = 0; i < size; ++i){sum += i;}return sum;}static int testReentrantLock(){try{lock.lock();int sum = 0;for(int i = 0; i < size; ++i){sum += i;}return sum;}finally{lock.unlock();}}}

加上total統計的測試代碼:

import java.util.concurrent.locks.ReentrantLock;import org.apache.commons.lang3.time.StopWatch;public class XXX {static ReentrantLock lock = new ReentrantLock(false);static int size = 100;static int count = 100000000;static StopWatch watch = new StopWatch();public static void main(String[] args) {noLockTime();noLockTime();noLockTime();syncTime();syncTime();syncTime();ReentrantTime();ReentrantTime();ReentrantTime();}static void noLockTime(){int total = 0;watch.reset();watch.start();for(int i = 0; i < count; ++i){//testNotLock();total += testNotLock();}watch.stop();System.out.println("noLockTime: " + watch);System.out.println("total:" + total);}static void syncTime(){int total = 0;watch.reset();watch.start();for(int i = 0; i < count; ++i){//testSync();total += testSync();}watch.stop();System.out.println("syncTime: " + watch);System.out.println("total:" + total);}static void ReentrantTime(){int total = 0;watch.reset();watch.start();for(int i = 0; i < count; ++i){//testReentrantLock();total += testReentrantLock();}watch.stop();System.out.println("ReentrantTime: " + watch);System.out.println("total:" + total);}static int testNotLock(){int sum = 0;for(int i = 0; i < size; ++i){sum += i;}return sum;}static synchronized int testSync(){int sum = 0;for(int i = 0; i < size; ++i){sum += i;}return sum;}static int testReentrantLock(){try{lock.lock();int sum = 0;for(int i = 0; i < size; ++i){sum += i;}return sum;}finally{lock.unlock();}}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.