美文网首页
ReentrantLock

ReentrantLock

作者: yongguang423 | 来源:发表于2018-05-04 12:36 被阅读9次

    重入锁,建议应用的同步方式。相对效率比synchronized高。量级较轻。
    synchronized在JDK1.5版本开始,尝试优化。到JDK1.7版本后,优化效率已经非常好了。在绝对效率上,不比reentrantLock差多少。
    使用重入锁,必须必须必须手工释放锁标记。一般都是在finally代码块中定义释放锁标记的unlock方法。

    锁的实现:

    Synchronized是依赖于JVM实现的,而ReenTrantLock是JDK实现的,有什么区别,说白了就类似于操作系统来控制实现和用户自己敲代码实现的区别。前者的实现是比较难见到的,后者有直接的源码可供阅读。

    性能的区别:

    在Synchronized优化以前,synchronized的性能是比ReenTrantLock差很多的,但是自从Synchronized引入了偏向锁,轻量级锁(自旋锁)后,两者的性能就差不多了,在两种方法都可用的情况下,官方甚至建议使用synchronized,其实synchronized的优化我感觉就借鉴了ReenTrantLock中的CAS技术。都是试图在用户态就把加锁问题解决,避免进入内核态的线程阻塞。

    功能区别:

    便利性:很明显Synchronized的使用比较方便简洁,并且由编译器去保证锁的加锁和释放,而ReenTrantLock需要手工声明来加锁和释放锁,为了避免忘记手工释放锁造成死锁,所以最好在finally中声明释放锁。

    锁的细粒度和灵活度:很明显ReenTrantLock优于Synchronized

    /**
     * ReentrantLock
     */
    package com.sxt.concurrent.t03;
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Test_01 {
        Lock lock = new ReentrantLock();
        
        void m1(){
            try{
                lock.lock();
                for(int i = 0; i < 10; i++){
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println("m1() method " + i);
                }
            }catch(InterruptedException e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
        
        void m2(){
            lock.lock();
            System.out.println("m2() method");
            lock.unlock();
        }
        
        public static void main(String[] args) {
            final Test_01 t = new Test_01();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m1();
                }
            }).start();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m2();
                }
            }).start();
        }
    }
    
    
    /**
     * 尝试锁
     */
    package com.sxt.concurrent.t03;
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Test_02 {
        Lock lock = new ReentrantLock();
        
        void m1(){
            try{
                lock.lock();
                for(int i = 0; i < 10; i++){
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println("m1() method " + i);
                }
            }catch(InterruptedException e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
        
        void m2(){
            boolean isLocked = false;
            try{
                isLocked = lock.tryLock(5, TimeUnit.SECONDS);
                if(isLocked){
                    System.out.println("m2() method synchronized");
                }else{
                    System.out.println("m2() method unsynchronized");
                }
            }catch(InterruptedException e){
                e.printStackTrace();
            }finally{
                if(isLocked){
                    lock.unlock();
                }
            }
        }
        
        public static void main(String[] args) {
            final Test_02 t = new Test_02();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m1();
                }
            }).start();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m2();
                }
            }).start();
        }
    }
    
    
    /**
     * 可打断
     */
    package com.sxt.concurrent.t03;
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Test_03 {
        Lock lock = new ReentrantLock();
        
        void m1(){
            try{
                lock.lock();
                for(int i = 0; i < 5; i++){
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println("m1() method " + i);
                }
            }catch(InterruptedException e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
        }
        
        void m2(){
            try{
                lock.lockInterruptibly();
                System.out.println("m2() method");
            }catch(InterruptedException e){
                System.out.println("m2() method interrupted");
            }finally{
                try{
                    lock.unlock();
                }catch(Exception e){
                    
                }
            }
        }
        
        public static void main(String[] args) {
            final Test_03 t = new Test_03();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m1();
                }
            }).start();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    t.m2();
                }
            });
            t2.start();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            t2.interrupt();
        }
    }
    
    

    公平锁

    公平锁
    /**
     * 公平锁
     */
    package com.sxt.concurrent.t03;
    
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Test_04 {
        
        public static void main(String[] args) {
            TestReentrantlock t = new TestReentrantlock();
            //TestSync t = new TestSync();
            Thread t1 = new Thread(t);
            Thread t2 = new Thread(t);
            t1.start();
            t2.start();
        }
    }
    
    class TestReentrantlock extends Thread{
        private static ReentrantLock lock = new ReentrantLock(true);
        public void run(){
            for(int i = 0; i < 5; i++){
                lock.lock();
                try{
                    System.out.println(Thread.currentThread().getName() + " get lock");
                }finally{
                    lock.unlock();
                }
            }
        }
        
    }
    
    class TestSync extends Thread{
        public void run(){
            for(int i = 0; i < 5; i++){
                synchronized (this) {
                    System.out.println(Thread.currentThread().getName() + " get lock in TestSync");
                }
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:ReentrantLock

          本文链接:https://www.haomeiwen.com/subject/pirdrftx.html