美文网首页
主要并发工具类-ReentrantLock的使用

主要并发工具类-ReentrantLock的使用

作者: 飞奔吧牛牛 | 来源:发表于2020-02-10 05:21 被阅读0次

    ReentrantLock 在使用上比synchronized稍微复杂点,需要显示的获取锁和释放锁。
    synchronized属于非公平锁,当多个线程去竞争同一个锁时,具体哪个线程会获取到锁不确定。ReentrantLock 除了支持非公平锁外,还支持公平锁,即获取锁的先后顺序已经确定,后来的会排到最后。
    基本使用形式:

     ReentrantLock lock = new ReentrantLock();
            lock.lock();
            try {
                System.out.println("do something");
            } finally {
                lock.unlock();
            }
    
    

    常用的四个方法:
    lock.lock() 获取锁
    lock.unLock() 释放锁
    lock.tryLock() 立即去获取锁,获取到返回true,获取不到返回false
    lock.tryLock(TimeOut,TimeUnit) 在一段时间内尝试获取锁,在这段时间内获取到了锁,返回true,超时后返回false。

    以上四个方法的使用:
    1.初始化lock对象

    ReentrantLock lock = new ReentrantLock();
    

    2.在线程t1中使用锁,获取锁后休眠3秒。休眠完后,释放锁

     Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + " lock success");
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        System.out.println(Thread.currentThread().getName()+" unlock");
                        lock.unlock();
                    }
                }
            });
    

    3.在线程t2中尝试获取锁,成功失败都打印相应信息。

            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (lock.tryLock(1, TimeUnit.SECONDS)) {
                            System.out.println(Thread.currentThread().getName() + " tryLock success");
                            try {
                                TimeUnit.SECONDS.sleep(1);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            } finally {
                                lock.unlock();
                            }
                        } else {
                            System.out.println(Thread.currentThread().getName() + "tryLock failure");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        System.out.println("等待获取锁时被打断");
                    }
                }
            });
    
    

    4.确保t1先执行,再执行t2。

        t1.start();
            TimeUnit.SECONDS.sleep(1);
            t2.start();
    

    4.1 tryLock等待时间超时的情况。
    t1先执行,拿到锁后立刻休眠三秒。t1执行一秒后,t2执行。这时t2 tryLock(1, TimeUnit.SECONDS),由于在这一秒内,锁一直被t1持有,
    超时后拿不到锁,故打印:Thread-1tryLock failure。之后t1休眠完毕,释放锁。

    Thread-0 lock success
    Thread-1tryLock failure
    Thread-0 unlock
    

    4.2 tryLock成功获取到锁的情况。
    修改等待获取锁的时间,即if (lock.tryLock(3, TimeUnit.SECONDS))。
    由于t2 tryLock等待的时间足够长,当t1执行完毕后释放了锁,这时,还在t2 tryLock等待时间之内,所以会立即获取锁。

    Thread-0 lock success
    Thread-0 unlock
    Thread-1 tryLock success
    

    可见ReentrantLock功能更多,当sychronized不能满足需求时,可以使用ReentrantLock。

    相关文章

      网友评论

          本文标题:主要并发工具类-ReentrantLock的使用

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