美文网首页
Lock和Condition(可重入锁)

Lock和Condition(可重入锁)

作者: 刘彦青 | 来源:发表于2019-10-16 23:59 被阅读0次

    Lock有别于synchronized隐式锁的三个特征:能够响应中断。支持超时和非阻塞地获取锁,也就是说lock比synchronized的功能丰富。

    JavaSDK并发包通过Lock和Condition两个接 口来实现管程,其中Lock用于解决互斥问题,Condition用于解决同步问题 。

    Lock接口的三个方法:

    //  ⽀持中断的API 
    void    lockInterruptibly() throws  InterruptedException; 
    //  ⽀持超时的API
    boolean tryLock(long time, TimeUnit unit) throws    InterruptedException; 
    //  ⽀持⾮阻塞获取锁的API 
    boolean tryLock();
    

    如何保证可见性

    class X {   
        private final Lock  rtl =   new ReentrantLock();        
        int value;      
        public  void    addOne()    {               
            //  获取锁             
            rtl.lock();                     
            try {                       
                value+=1;               
            } finally {                     
                //  保证锁能释放                      
                rtl.unlock();               
            }       
        } 
    }
    

    什么是可重入锁(ReentrantLock)

    指线程可以重复获取同一把锁 。

    //⽆参构造函数:默认⾮公平锁 
    public  ReentrantLock() {               
        sync    =   new NonfairSync(); 
    } 
    //根据公平策略参数创建锁 fair=true是公平锁
    public  ReentrantLock(boolean fair){                
        sync = fair ? new FairSync() : new NonfairSync(); 
    }
    

    非公平可重入锁示例:

    线程可以重复获取同一把锁。

       /**
         * 当线程t执行到①处时,已经获取到了锁rtl,
         * 当在①处调用get()方法时,会在②再次对锁rtl执行加锁操作。
         * 此时,如果锁   rtl 是可重入的,那么线程T1可以再次加锁成功;如果锁    rtl 是不可重入`     * 的,那么线程t此时会被阻塞。
         */
    public class ReentrantLockExample {
        private final Lock rtl = new ReentrantLock();
        int value;
    
        public int get() {
            //  获取锁
            rtl.lock(); //②
            try {
                return value;
            } finally {
                //  保证锁能释放
                rtl.unlock();
            }
        }
    
        public void addOne() {
            //  获取锁
            rtl.lock();
            try {
                value = 1 + get();    //①
            } finally {
                //  保证锁能释放
                rtl.unlock();
            }
        }
    

    可重入函数: 多个线程可以同时调用该函数。

    可重入函数是线程安全的。

    非公平锁与公平锁

    ReentrantLock这个类有两个构造函数,一个是无参构造函数,一个是传入fair参数的构造函数。fair参数代表的是锁的公平策略,如果传入true就表示需要构造一个公平锁,反 之则表示要构造一个非公平锁。

     //创建ReentrantLock时传入true是公平锁
    private final Lock rtl = new ReentrantLock(true);
     //false或者不传值是非公平锁
    private final Lock rtl = new ReentrantLock();
    

    用锁的最佳实践

    1. 永远只再更新对象的成员变量时加锁。
    2. 永远只在访问可变的成员变量时加锁。
    3. 永远不再调用其它对象的方法时加锁。
    4. 减少所得持有时间,减小锁的粒度。

    同步与异步

    • 调用方法如果需要等待结果,就是同步;如果不需要等待结果就是异步。
    • 同步是Java代码默认的处理方式。

    如何实现程序支持异步:

    1. 异步调用: 调用方创建一个子线程,再子线程中执行方法调用。
    2. 异步方法: 被调用方;方法实现的时候,创建一个显得线程执行主要逻辑,主线程直接return。

    **** 码字不易如果对你有帮助请给个关注****

    **** 爱技术爱生活 QQ群: 894109590****

    相关文章

      网友评论

          本文标题:Lock和Condition(可重入锁)

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