The contrast between Java locks

The difference between synchronized and java.util.concurrent.lock.Lock

  • Implementation level is not the same. synchronized keyword in Java, JVM level to achieve locking and releasing locks; Lock is an interface to achieve locking and releasing locks in the code level
  • Whether to automatically release the lock. the code execution thread synchronized automatically releases the lock when finished or abnormal; Lock does not automatically release the lock, it is necessary finally {} block explicitly release the lock
  • Whether you have been waiting for. synchronized causes the thread can not get the lock has been waiting for; Lock can be set up to try to acquire locks or locking failure to obtain a certain timeout
  • Acquiring the lock success if known. synchronized not know whether to acquire a lock success; Lock can get locked whether successful tryLock
  • Functional complexity. synchronized reentrant lock, can not be interrupted, non-fair; Lock reentrant, it can be determined, be fair and unfair, read-write locks subdivided efficiency

 

The difference between java.util.concurrent.lock.Lock and java.util.concurrent.lock.ReadWriteLock

  • ReadWriteLock defines acquire read and write locks interface, not mutually exclusive read lock, ideal for reading, less write scenes

 

Applicable scene

  • JDK 1.6 start of synchronized manner shackles optimized, joined the biased locking, lightweight locks and lock promotion mechanisms, performance has been greatly improved. Performance and almost ReentrantLock
  • The case of reading and writing small, consider using ReadWriteLock 

 

synchronized, ReentrantLock, ReentrantReadWriteLock 990 threads started reading shared variables, 10 threads write shared variables

package constxiong.concurrency.a020;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * JDK 1.8 in locking performance test
 * @author ConstXiong
 */
public class TestLockPerformance {
    
    public  static Object obj = new new Object (); // for obtaining synchronized lock
    
    public  static Lock Lock = new new of ReentrantLock (); // reentrant lock
    
    public static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();//读写锁
    
    public static final int READ = 0;
    
    public static final int WRITE = 1;
    
    // UUID, a random string 
    public  static String UUID = UUID.randomUUID () toString ().;

    public static void main(String[] args) throws InterruptedException {
//        testSynchronized(1000);
        
        testReentrantLock(1000);
        
//         test read write lock (1000); 
    }
    
    public static void testSynchronized(int threadNum) throws InterruptedException {
        long t1 = System.currentTimeMillis();
        List <the Thread> = tlist new new the ArrayList <the Thread> ();
         // start threadNum - rounded up to (0.01 * threadNum) threads read uuid, rounding up (0.01 * threadNum) threads write UUID 
        for ( int I = 0 ; I <threadNum; I ++ ) {
            Thread t;
            if (i % 100 == 0) {
                t = new Thread(new WorkerSynchronized(WRITE));
            } else {
                t = new Thread(new WorkerSynchronized(READ));
            }
            t.start (); // start the thread 
            tList.add (t);
        }
        
        for (Thread t : tList) {
            t.join();
        }
        
        long t2 = System.currentTimeMillis();
        System.out.println("testSynchronized 耗时:" + (t2 - t1));
    }
    
    public static void testReentrantLock(int threadNum) throws InterruptedException {
        long t1 = System.currentTimeMillis();
        List <the Thread> = tlist new new the ArrayList <the Thread> ();
         // start threadNum - rounded up to (0.01 * threadNum) threads read uuid, rounding up (0.01 * threadNum) threads write UUID 
        for ( int I = 0 ; I <threadNum; I ++ ) {
            Thread t;
            if (i % 100 == 0) {
                t = new Thread(new WorkerReentrantLock(WRITE));
            } else {
                t = new Thread(new WorkerReentrantLock(READ));
            }
            t.start (); // start the thread 
            tList.add (t);
        }
        
        for (Thread t : tList) {
            t.join();
        }
        
        long t2 = System.currentTimeMillis();
        System.out.println("testReentrantLock 耗时:" + (t2 - t1));
    }
    
    public static void testReadWriteLock(int threadNUm) throws InterruptedException {
        long t1 = System.currentTimeMillis();
        List <the Thread> = tlist new new the ArrayList <the Thread> ();
         // start threadNum - rounded up to (0.01 * threadNum) threads read uuid, rounding up (0.01 * threadNum) threads write UUID 
        for ( int I = 0 ; I <ThreadNum; I ++ ) {
            Thread t;
            if (i % 100 == 0) {
                t = new Thread(new WorkerReadWriteLock(WRITE));
            } else {
                t = new Thread(new WorkerReadWriteLock(READ));
            }
            t.start (); // start the thread 
            tList.add (t);
        }
        
        for (Thread t : tList) {
            t.join();
        }
        
        long t2 = System.currentTimeMillis();
        System.out.println("testReadWriteLock 耗时:" + (t2 - t1));
    }
    
}

// worker thread, use the synchronized keyword lock 
class WorkerSynchronized the implements Runnable {
     // 0 the Read-; 1-the Write 
    Private  int of the type;
    
    WorkerSynchronized(int type) {
        this.type = type;
    }
    
    // locking TestLockPerformance.uuid variables read, and print 
    Private  void Read () {
         the synchronized (TestLockPerformance.obj) {
             // Sleep 20 ms, time-consuming task simulate 
            the try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
            System.out.println(Thread.currentThread().getName() + 
                    " read uuid = " +  TestLockPerformance.uuid);
        }
    }
    
    // locked write TestLockPerformance.uuid variables, and print 
    Private  void the Write () {
         the synchronized (TestLockPerformance.obj) {
             // sleep 20 milliseconds, analog time-consuming task of 
            the try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
            TestLockPerformance.uuid = UUID.randomUUID().toString();
            System.out.println(Thread.currentThread().getName() + 
                    " write uuid = " +  TestLockPerformance.uuid);
        }
    }
    
    @Override
    public  void RUN () {
         // type = 0, the read thread TestLockPerformance.uuid variable 
        IF (type == 0 ) {
            read();
        // type =. 1, thread generation uuid, write TestLockPerformance.uuid variable 
        } the else {
            write();
        }
    }
}

// working thread lock used ReentrantLock 
class WorkerReentrantLock the implements the Runnable {
     // 0-Read; Write. 1- 
    Private  int type;
    
    WorkerReentrantLock(int type) {
        this.type = type;
    }
    
    // locked read TestLockPerformance.uuid variables, and print 
    Private  void the Read () {
        TestLockPerformance.lock.lock();
        the try {
             // Sleep 20 ms, time-consuming task simulate 
            the try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
            System.out.println(Thread.currentThread().getName() + 
                    " read uuid = " +  TestLockPerformance.uuid);
        } finally {
            TestLockPerformance.lock.unlock();
        }
        
    }
    
    // locked write TestLockPerformance.uuid variables, and print 
    Private  void the Write () {
        TestLockPerformance.lock.lock();
        the try {
             // Sleep 20 ms, time-consuming task simulate 
            the try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
            TestLockPerformance.uuid = UUID.randomUUID().toString();
            System.out.println(Thread.currentThread().getName() + 
                    " write uuid = " +  TestLockPerformance.uuid);
        } finally {
            TestLockPerformance.lock.unlock();
        }
    }
    
    @Override
    public  void RUN () {
         // type = 0, the read thread TestLockPerformance.uuid variable 
        IF (type == 0 ) {
            read();
        // type =. 1, thread generation uuid, write TestLockPerformance.uuid variable 
        } the else {
            write();
        }
    }
}


// worker thread, use the keyword lock ReentrantReadWriteLock 
class WorkerReadWriteLock the implements Runnable {
     // 0 the Read-; 1-the Write 
    Private  int of the type;
    
    WorkerReadWriteLock(int type) {
        this.type = type;
    }
    
    // locked read TestLockPerformance.uuid variables, and print 
    Private  void the Read () {
        TestLockPerformance.readWriteLock.readLock().lock();
        the try {
             // Sleep 20 ms, time-consuming task simulate 
            the try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
            System.out.println(Thread.currentThread().getName() + 
                    " read uuid = " +  TestLockPerformance.uuid);
        } finally {
            TestLockPerformance.readWriteLock.readLock().unlock();
        }
    }
    
    // locked write TestLockPerformance.uuid variables, and print 
    Private  void the Write () {
        TestLockPerformance.readWriteLock.writeLock().lock();
        the try {
             // Sleep 20 ms, time-consuming task simulate 
            the try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
            TestLockPerformance.uuid = UUID.randomUUID().toString();
            System.out.println(Thread.currentThread().getName() + 
                    " write uuid = " +  TestLockPerformance.uuid);
        } finally {
            TestLockPerformance.readWriteLock.writeLock().unlock();
        }
    }
    
    @Override
    public  void RUN () {
         // type = 0, the read thread TestLockPerformance.uuid variable 
        IF (type == 0 ) {
            read();
        // type =. 1, thread generation uuid, write TestLockPerformance.uuid variable 
        } the else {
            write();
        }
    }
}

 

 

Call the test method 

testSynchronized (1000);

 

time consuming

Thread-0 write uuid = b7fb63d7-79cc-4cc0-84ed-5a9cd4de6824
Thread-252 read uuid = b7fb63d7-79cc-4cc0-84ed-5a9cd4de6824
Thread-251 read uuid = b7fb63d7-79cc-4cc0-84ed-5a9cd4de6824
.
.
.
Thread-255 read uuid = d666bfe6-dc71-4df2-882a-d530a59d7e92
Thread-254 read uuid = d666bfe6-dc71-4df2-882a-d530a59d7e92
Thread-253 read uuid = d666bfe6-dc71-4df2-882a-d530a59d7e92
testSynchronized time: 22991

 

 

Call the test method 

test reentrant lock (1000);

 

time consuming

Thread-0 write uuid = 4352eb13-d284-47ec-8caa-fc81d91d08e1
Thread-1 read uuid = 4352eb13-d284-47ec-8caa-fc81d91d08e1
Thread-485 read uuid = 4352eb13-d284-47ec-8caa-fc81d91d08e1
.
.
.
Thread-997 read uuid = 9d7f0a78-5eb7-4506-9e98-e8e9a7a717a5
Thread-998 read uuid = 9d7f0a78-5eb7-4506-9e98-e8e9a7a717a5
Thread-999 read uuid = 9d7f0a78-5eb7-4506-9e98-e8e9a7a717a5
testReentrantLock time: 22935

 

 

Call the test method 

test read write lock (1000);

 

time consuming

Thread-0 write uuid = 81c13f80-fb19-4b27-9d21-2e99f8c8acbd
Thread-277 read uuid = 81c13f80-fb19-4b27-9d21-2e99f8c8acbd
Thread-278 read uuid = 81c13f80-fb19-4b27-9d21-2e99f8c8acbd
.
.
.
Thread-975 read uuid = 35be0359-1973-4a4f-85b7-918053d841f7
Thread-971 read uuid = 35be0359-1973-4a4f-85b7-918053d841f7
Thread-964 read uuid = 35be0359-1973-4a4f-85b7-918053d841f7
testReadWriteLock time: 543

 

 

Consuming tests can be seen, the use of synchronized and time-consuming ReentrantLock similar; reading but because threads 990, threads 10 to write, using 543 msec ReentrantReadWriteLock consuming.

 

PS: JDK concurrency package of tools, there are a lot of tools for a particular scene, we continue to explore the back.

       


Java interview questions summary, there is always a stuck you!

 

Guess you like

Origin www.cnblogs.com/ConstXiong/p/11687834.html