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/>