Compare the synchronization performance of reentrantlock, synchronized, and semaphore.

Source: Internet
Author: User
Tags finally block

To compare the performance of reentrantlock and synchronized, a performance test is performed:

Reference http://zzhonghe.javaeye.com/blog/826162

 

Conclusion:

(1) The performance of using lock is improved by 4 ~ compared with the synchronized keyword ~ 5 times;

(2) The synchronization speed using semaphores is about 10 ~ slower than synchronized ~ 20%;

(3) The atomicinter speed of the atomic package is one order of magnitude faster than the lock speed.

 

Reentrantlock class
The lock framework in Java. util. Concurrent. Lock is an abstraction of locking. It allows implementation of locking as a Java class, rather than implementation as a language feature. This leaves space for multiple lock implementations, and various implementations may have different scheduling methods.AlgorithmPerformance features or locking semantics. The reentrantlock class implements lock, which has the same concurrency and memory semantics as synchronized, but adds a similar lock vote,Characteristics of timed lock wait and interruptible lock wait. In addition, it provides better performance in the case of fierce competition. (In other words, when many threads want to access shared resources, JVM can spend less time scheduling threads and spend more time on execution threads .)

What does the reentrant lock mean? To put it simply, there is a lock-related acquisition counter. If a thread that owns the lock gets the lock again, it will add 1 to the acquisition counter, then the lock must be released twice before it can be truly released. This imitates synchronized semantics. If a thread enters the synchronized block protected by the monitor that the thread already owns, the thread is allowed to continue. When the thread exits the second (or later) the synchronized block is released only when the thread exits the first synchronized block protected by the monitor.

In viewCodeIn the example, we can see that there is a significant difference between lock and synchronized --Lock must be released in the finally Block. Otherwise, if the protected code throws an exception, the lock may never be released! This difference may seem insignificant, but in fact it is extremely important. If you forget to release the lock in the Finally blockProgramLeave a scheduled bomb in. When one day the bomb explosion occurs, it takes a lot of effort to find the source. With synchronization, JVM ensures that the lock is automatically released.

 

Source code of test

Public abstract class test {<br/> protected string ID; <br/> protected javasicbarrier barrier; <br/> protected long count; <br/> protected int threadnum; <br/> protected executorservice executor; </P> <p> Public test (string ID, icicbarrier barrier, Long Count, int threadnum, <br/> executorservice executor) {<br/> This. id = ID; <br/> This. barrier = barrier; <br/> This. count = count; <br/> This. threadnum = threadnum; <br/> this.exe cutor = executor; <br/>}</P> <p> Public void starttest () {</P> <p> long start = system. currenttimemillis (); </P> <p> for (Int J = 0; j <threadnum; j ++) {<br/> executor.exe cute (New thread () {<br/> @ override <br/> Public void run () {<br/> for (INT I = 0; I <count; I ++) {<br/> test (); <br/>}</P> <p> try {<br/> barrier. await (); </P> <p >}catch (interruptedexception e) {<br/> E. printstacktrace (); <br/>} catch (brokenbarrierexception e) {<br/> E. printstacktrace (); <br/>}< br/> }); <br/>}</P> <p> try {<br/> barrier. await (); <br/>}catch (interruptedexception e) {<br/> E. printstacktrace (); <br/>} catch (brokenbarrierexception e) {<br/> E. printstacktrace (); <br/>}</P> <p> // After All threads are executed, this step is taken. <br/> long duration = system. currenttimemillis ()-start; <br/> system. out. println (ID + "=" + duration); <br/>}</P> <p> protected abstract void test (); <br/>}< br/>

 

Test reentrelocktest source code

Import thread. test. test; </P> <p> public class reentrelocktest {<br/> Private Static Long Count = 1000000; <br/> Private Static lock = new reentrantlock (); <br/> Private Static long lockcounter = 0; <br/> Private Static long synccounter = 0; <br/> Private Static long semacounter = 0; <br/> Private Static atomiclong atomiccounter = new atomiclong (0); <br/> private static object synclock = new object (); <br/> Private Static semaphore mutex = new semaphore (1); </P> <p> Public static void testlock (INT num, int threadcount) {</P> <p >}</P> <p> static long getlock () {<br/> lock. lock (); <br/> try {<br/> return lockcounter; <br/>}finally {<br/> lock. unlock (); <br/>}</P> <p> static long getsync () {<br/> synchronized (synclock) {<br/> return synccounter; <br/>}</P> <p> static long getatom () {<br/> return atomiccounter. get (); <br/>}</P> <p> static long getsemaphore () throws interruptedexception {<br/> mutex. acquire (); </P> <p> try {<br/> return semacounter; <br/>} finally {<br/> mutex. release (); <br/>}</P> <p> static long getlockinc () {<br/> lock. lock (); <br/> try {<br/> return ++ lockcounter; <br/>}finally {<br/> lock. unlock (); <br/>}</P> <p> static long getsyncinc () {<br/> synchronized (synclock) {<br/> return ++ synccounter; <br/>}</P> <p> static long getatominc () {<br/> return atomiccounter. getandincrement (); <br/>}</P> <p> static class sematest extends test {</P> <p> Public sematest (string ID, cyclicbarrier barrier, long Count, <br/> int threadnum, executorservice executor) {<br/> super (ID, barrier, Count, threadnum, executor ); <br/>}</P> <p> @ override <br/> protected void test () {<br/> try {<br/> getsemaphore (); <br/>} catch (interruptedexception e) {<br/> E. printstacktrace (); <br/>}</P> <p> static class locktest extends test {</P> <p> Public locktest (string ID, extends icbarrier barrier, Long Count, <br/> int threadnum, executorservice executor) {<br/> super (ID, barrier, Count, threadnum, executor ); <br/>}</P> <p> @ override <br/> protected void test () {<br/> getlock (); <br/>}</P> <p> static class synctest extends test {</P> <p> Public synctest (string ID, extends icbarrier barrier, Long Count, <br/> int threadnum, executorservice executor) {<br/> super (ID, barrier, Count, threadnum, executor ); <br/>}</P> <p> @ override <br/> protected void test () {<br/> getsync (); <br/>}</P> <p> static class atomictest extends test {</P> <p> Public atomictest (string ID, extends icbarrier barrier, Long Count, <br/> int threadnum, executorservice executor) {<br/> super (ID, barrier, Count, threadnum, executor ); <br/>}</P> <p> @ override <br/> protected void test () {<br/> getatom (); <br/>}</P> <p> Public static void test (string ID, Long Count, int threadnum, <br/> executorservice executor) {</P> <p> final javasicbarrier barrier = new javasicbarrier (threadnum + 1, <br/> New thread () {</P> <p> @ override <br/> Public void run () {</P> <p >}< br/> }); </P> <p> system. out. println ("=============================== "); <br/> system. out. println ("Count =" + Count + "/t" + "Thread Count =" <br/> + threadnum ); </P> <p> New locktest ("Lock", barrier, Count, threadnum, executor ). starttest (); <br/> New synctest ("sync", barrier, Count, threadnum, executor ). starttest (); <br/> New atomictest ("atom", barrier, Count, threadnum, executor) <br/>. starttest (); <br/> New sematest ("Sema", barrier, Count, threadnum, executor) <br/>. starttest (); <br/> system. out. println ("=============================== "); <br/>}</P> <p> Public static void main (string [] ARGs) {<br/> for (INT I = 1; I <5; I ++) {<br/> executorservice executor = executors. newfixedthreadpool (10 * I); <br/> test ("", count * I, 10 * I, executor ); <br/>}< br/>

 

 

Result

 

===============================< Br/> COUNT = 1000000 thread count = 10 <br/> lock = 953 <br/> sync = 3781 <br/> atom = 78 <br/> Sema = 4922 <br/> ====== ====================================< br/>====================== ======================< br/> COUNT = 2000000 thread count = 20 <br/> lock = 1906 <br/> sync = 8469 <br/> atom = 172 <br/> Sema = 9719 <br/> ==================== ============< br/>==================================== ===< br/> COUNT = 3000000 thread count = 30 <br/> lock = 2890 <br/> sync = 12641 <br/> atom = 219 <br/> sema = 15015 <br/> ===============================< br/ >========================================< br/> COUNT = 4000000 thread count = 40 <br/> lock = 3844 <br/> sync = 17141 <br/> atom = 343 <br/> Sema = 19782 <br/> ==== ======================================< br/>

 

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.