Java Concurrency-Lock mechanism (1) Lock and ReentrantLock

Source: Internet
Author: User

 

The previous sections mainly talk about atomic operations. As for some problems or traps related to atomic operations, they will be explained in the final summary. Starting from this chapter, we will spend a small amount of time talking about the lock mechanism.

In the previous chapter, we talked about the lock mechanism and some related concepts and design ideas for atomic operations. In the next article, we will try our best to study the lock mechanism in depth and understand the principles and practical application scenarios.

Although synchronized is simple enough in syntax, it can only be used before JDK 5, but because it is an exclusive lock, its performance is not high, therefore, JDK 5 and later began to use JNI to implement more advanced lock implementation.

The lock in JDK 5 is an interface.Java. util. concurrent. locks. Lock. In additionJava. util. concurrent. locks. ReadWriteLockProvides a pair of locks for read/write concurrency. According to the preceding rulesJava. util. concurrent. locks. Lock.

 

Void lock ();

Obtain the lock.

If the lock is unavailable, the current thread is disabled for Thread Scheduling and remains in sleep state until the lock is obtained.

Void lockInterruptibly () throws InterruptedException;

If the current thread is not interrupted, the lock is obtained.

If the lock is available, the lock is obtained and immediately returned.

If the lock is unavailable, the current thread is disabled for Thread Scheduling and remains in sleep state until one of the following conditions occurs:

  • The lock is obtained by the current thread; or another thread interrupts the current thread and supports the interruption of the lock.

    If the current thread:

    • The thread interruption status has been set when you enter this method; or the thread is interrupted when the lock is obtained and the thread can be interrupted when the lock is obtained.InterruptedExceptionAnd clear the interrupted status of the current thread.

      Condition newCondition ();

      Bind to thisLockNew instanceConditionInstance. The next section will focus on Condition, which is not described too much here.

      Boolean tryLock ();

      The lock is obtained only when the lock is idle.

      If the lock is available, the lock is obtained and the returned value is immediately.true. If the lock is unavailable, this method returns the value immediately.false.

      It is usually useful for operations that do not have to obtain the lock.

      Boolean tryLock (long time, TimeUnit unit) throws InterruptedException;

      If the lock is idle within the specified waiting time and the current thread is not interrupted, the lock is obtained.

      If the lock is available, this method returns the value immediately.true. If the lock is unavailable, the current thread is disabled for Thread Scheduling purposes and remains in sleep state until one of the following three conditions occurs:

      • The lock is obtained by the current thread; or another thread interrupts the current thread and supports the interruption of the lock; or the lock has exceeded the specified waiting time.

        If the lock is obtained, the returned value istrue.

        If the current thread:

        • The thread interruption status has been set when you enter this method; or the thread is interrupted when the lock is obtained and the thread can be interrupted when the lock is obtained.InterruptedExceptionAnd clears the interrupted status of the current thread.

          If the specified wait time is exceeded, the returned value isfalse. If time is less than or equal to 0, this method will not wait.

          Void unlock ();

          Release the lock. It corresponds to lock (), tryLock (), tryLock (xx), lockInterruptibly (), and so on. If it succeeds, it should correspond to an unlock (), which can avoid deadlocks or waste of resources.

           

          Compared with the relatively empty API, let's look at a practical example. The following code implements an operation similar to AtomicInteger.

          Package xylz. study. concurrency. lock;

          Import java. util. concurrent. locks. Lock;
          Import java. util. concurrent. locks. ReentrantLock;

          Public class AtomicIntegerWithLock {

          Private int value;

          Private Lock lock = new ReentrantLock ();

          Public AtomicIntegerWithLock (){
          Super ();
          }

          Public AtomicIntegerWithLock (int value ){
          This. value = value;
          }

          Public final int get (){
          Lock. lock ();
          Try {
          Return value;
          } Finally {
          Lock. unlock ();
          }
          }

          Public final void set (int newValue ){
          Lock. lock ();
          Try {
          Value = newValue;
          } Finally {
          Lock. unlock ();
          }

          }

          Public final int getAndSet (int newValue ){
          Lock. lock ();
          Try {
          Int ret = value;
          Value = newValue;
          Return ret;
          } Finally {
          Lock. unlock ();
          }
          }

          Public final boolean compareAndSet (int exact CT, int update ){
          Lock. lock ();
          Try {
          If (value = CT ){
          Value = update;
          Return true;
          }
          Return false;
          } Finally {
          Lock. unlock ();
          }
          }

          Public final int getAndIncrement (){
          Lock. lock ();
          Try {
          Return value ++;
          } Finally {
          Lock. unlock ();
          }
          }

          Public final int getAndDecrement (){
          Lock. lock ();
          Try {
          Return value --;
          } Finally {
          Lock. unlock ();
          }
          }

          Public final int incrementAndGet (){
          Lock. lock ();
          Try {
          Return ++ value;
          } Finally {
          Lock. unlock ();
          }
          }

          Public final int decrementAndGet (){
          Lock. lock ();
          Try {
          Return -- value;
          } Finally {
          Lock. unlock ();
          }
          }

          Public String toString (){
          Return Integer. toString (get ());
          }
          }

          ClassAtomicIntegerWithLockIt is thread-safe, and a large number of Lock/unlock method pairs of the lock object are used in this structure. We can also see that ++/-- is used for auto-increment and auto-increment operations /--. The thread security is ensured because the Lock () method of the lock Object ensures that only one thread can have this Lock. It must be noted that an unlock () method is required for any lock () method. Generally, to ensure that the unlock method can always be executed, the unlock method is placed in the finally block. In additionJava. util. concurrent. locks. ReentrantLock. ReentrantLockObject. The next section describes how to design and implement this class as the unique implementation of Lock.

          Although synchronized implements the same semantics of Lock and syntax is much simpler than Lock, the former has much higher overhead than the latter. Perform a simple test.

          Public static void main (String [] args) throws Exception {
          Final int max = 10;
          Final int loopCount = 100000;
          Long costTime = 0;
          For (int m = 0; m <max; m ++ ){
          Long start1 = System. nanoTime ();
          Final AtomicIntegerWithLock value1 = new AtomicIntegerWithLock (0 );
          Thread [] ts = new Thread [max];
          For (int I = 0; I Ts [I] = new Thread (){
          Public void run (){
          For (int I = 0; I <loopCount; I ++ ){
          Value1.incrementAndGet ();
          }
          }
          };
          }
          For (Thread t: ts ){
          T. start ();
          }
          For (Thread t: ts ){
          T. join ();
          }
          Long end1 = System. nanoTime ();
          CostTime + = (end1-start1 );
          }
          System. out. println (cost1: + (costTime ));
          //
          System. out. println ();
          CostTime = 0;
          //
          Final Object lock = new Object ();
          For (int m = 0; m <max; m ++ ){
          StaticValue = 0;
          Long start1 = System. nanoTime ();
          Thread [] ts = new Thread [max];
          For (int I = 0; I Ts [I] = new Thread (){
          Public void run (){
          For (int I = 0; I <loopCount; I ++ ){
          Synchronized (lock ){
          ++ StaticValue;
          }
          }
          }
          };
          }
          For (Thread t: ts ){
          T. start ();
          }
          For (Thread t: ts ){
          T. join ();
          }
          Long end1 = System. nanoTime ();
          CostTime + = (end1-start1 );
          }
          //
          System. out. println (cost2: + (costTime ));
          }


          Static int staticValue = 0;

           

          In this example, 10 threads are started each time, and each thread calculates 100000 auto-increment operations and retests 10 times. The following is the result of a test:

          Cost1: 624071136

          Cost2: 2057847833

          Although the above example is not a very formal test case, the above example shows that the Lock performance is much better than synchronized. If you can, always use Lock to replace synchronized.

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.