In layman's Java Concurrency (6): Lock mechanism part 1[turn]

Source: Internet
Author: User
Tags finally block

The previous chapters mainly talk about atomic operations, as far as the questions related to atomic manipulation or traps are put in the final summary. This chapter begins with a small amount of space to talk about locking mechanisms.

The lock mechanism is discussed in the previous section, and some related concepts and design ideas are discussed for atomic operation. The following article, as far as possible in-depth study of the lock mechanism, and understand the principle and practical application of the situation.

Although synchronized is syntactically simple enough to use this implementation before JDK 5, because it is an exclusive lock, the performance is not high, so JDK 5 began with JNI to achieve a more advanced lock implementation.

The lock in JDK 5 is the interface Java.util.concurrent.locks.Lock. In addition, Java.util.concurrent.locks.ReadWriteLock provides a pair of locks that can be read and written concurrently. Based on the previous rules, we start with the Java.util.concurrent.locks.Lock API.

void Lock ();

Gets the lock.

If the lock is not available, the current thread is disabled for thread scheduling purposes, and the thread will remain dormant until the lock is acquired.

void Lockinterruptibly () throws interruptedexception;

Gets the lock if the current thread is not interrupted.

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

If the lock is not available, the current thread is disabled for thread scheduling purposes, and the thread will remain dormant until one of the following two situations occurs:

    • The lock is obtained by the current thread, or
    • One of the other threads interrupts the current thread and supports interrupts acquired by the lock.

If the current thread:

    • The interrupt state of the thread has been set when entering this method;
    • is interrupted while acquiring a lock, and supports interrupts acquired by the lock,

is thrown InterruptedException , and the current thread's interrupted state is cleared.

Condition newcondition ();

Returns a new instance bound to this Lock instance Condition . The next section will focus on condition, which does not introduce too much here.

Boolean Trylock ();

The lock is acquired only if the call to Shi is idle.

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

It is often useful for operations that do not have to acquire locks.

Boolean Trylock (long time, Timeunit unit) throws Interruptedexception;

Gets the lock if the lock is idle for a given wait time, and the current thread is not interrupted.

If the lock is available, this method returns the value immediately true . If the lock is not available, the current thread is disabled for thread scheduling purposes, and the thread will remain dormant until one of the following three situations occurs:

    • The lock is obtained by the current thread, or
    • One of the other threads interrupts the current thread and supports an interrupt for lock acquisition;
    • The specified wait time has been exceeded

If a lock is obtained, the value is returned true .

If the current thread:

    • The interrupt state of the thread has been set when entering this method;
    • is interrupted while acquiring a lock, and supports interrupts acquired by the lock,

will be thrown InterruptedException , and the current thread's interrupted state will be cleared.

If the specified wait time is exceeded, a value is returned false . If time is less than or equal to 0, the method will not wait at all.

void unlock ();

Release the lock. This corresponds to the operation of Lock (), Trylock (), Trylock (xx), lockinterruptibly (), and, if successful, a unlock (), which avoids deadlocks or wasted resources.

Look at a practical example compared to the more empty API. 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 expect, int update) {
     & nbsp;  Lock.lock ();
        try {
             if (value = = expect) {
                 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 ());
}
}

Class Atomicintegerwithlock are thread-safe, and the Lock/unlock method pair for the lock object is used extensively in this structure. It is also possible to see the use of ++/for self-increment and decrement operations--。 Thread safety is ensured because the lock () method of the lock object guarantees that only one thread can have this lock. It is necessary to note that for any one lock () method, a unlock () method is required, usually in order to ensure that the unlock method is always executed, the Unlock method is placed in the finally block. In addition, the Java.util.concurrent.locks.ReentrantLock.ReentrantLock object is used here, and the next section describes how this class is designed and implemented as the only implementation of lock.

Although synchronized implements the same semantics for lock and is much simpler in syntax than lock, the former is much more expensive than the latter. Do 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<max;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<max;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, each time you start 10 threads, each thread calculates 100,000 self-increment operations, repeats the test 10 times, and the following is the result of one of these tests:

cost1:624071136

cost2:2057847833

Although the above example is not a very formal test case, the above example shows that lock performance is much better than synchronized. It is a wise choice to always use lock instead of synchronized if you can.

In layman's Java Concurrency (6): Lock mechanism part 1[turn]

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.