ReentrantLock --- Lock显示锁系列( 手动管理锁)

内部锁(自动锁 JVM管理):通过synchronized关键字实现
显示锁(手动锁 手动管理锁 功能更多):通过java.concurrent.locks.Lock接口的实现类
 

  1.                                 ReentrantLock 可重入锁

允许同一线程重复获得该锁不会出现死锁等问题(synchronized就是可重入的)
公平锁:
synchronized默认是非公平锁,公平锁能保证先请求锁的线程拿到锁,避免线程饥饿问题等待过久,但是需要维护有序队列产生额外开销,据情况使用
new ReentrantLock(boolean) true开启公平锁

常用方法

lock() 获得锁  一般finally里unlock()释放锁,在中间区域属于同步代码块

    static Lock lock=new ReentrantLock();
    private static void test(){
        lock.lock();
         同步代码块
        lock.unlock();
    }    

证明ReentrantLock可重入性(线程1进入test又进入test2重复拿到锁对象) , 以及实现同步:

public class T3{
    static final Lock lock=new ReentrantLock();
    private static void test(){
           lock.lock();
            System.out.println(Thread.currentThread().getName()+"开始");
            test2();
            lock.unlock();
    } private static void test2(){
        lock.lock();
            System.out.println(Thread.currentThread().getName()+"执行2");
        lock.unlock();
    }
    public static void main(String[] args) {
        new Thread(T3::test).start();
        new Thread(T3::test).start();
    }
}
  • Lock.lockInterruptibly() 若当前线程未被interrupt()中断则获得锁,若被中断则抛出异常,让出锁
    一般搭配isAlive()检测某线程是否活动,是则interrupt()发出中断信号
  • Lock.tryLock() / (long, TimeUnit.SECONDS)  是否未被占有/ 指定秒数内未被占有
    interrupt() 同样可以使tryLock()为true

  • Condition Lock.newCondition() 返回的类型可以实现 等待/通知唤醒
    await() 当前线程丢弃锁进入睡眠
    signal() 从等待队列中唤醒第一个线程,使其尝试重新获取锁(一般放在句末搭配unlock释放)
     

    public static void main(String[] args) throws InterruptedException {
            Lock lock = new ReentrantLock();
            Condition condition = lock.newCondition();
    
            Thread t1 = new Thread(() -> {
                lock.lock();
                try {
                    System.out.println("线程1获取锁");
                    condition.await();
                    while (true){
                     if(lock.tryLock()){
                         System.out.println("线程1被唤醒"); //线程2唤醒后回调
                         break;
                     }else {
                         System.out.println("线程1睡觉中"); //线程2唤醒后回调
                     }
                    }
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            });
    
            Thread t2 = new Thread(() -> {
                lock.lock();
                try {
                    Thread.sleep(1000); //保证t1先启动
                    System.out.println("线程2获取锁");
                    condition.signal();
                    System.out.println("线程2唤醒线程1");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
    
                }
            });
            t1.start();
            t2.start();
    
    
        }

    Lock其他常用方法:
    int getHoldCount():返回当前线程调用lock()方法的次数
    int getQueueLength():返回正在等待获得锁的线程预估数
    int getWaitQueueLength(Condition condition):返回与condition条件相关等待线程预估数boolean hasQueuedThreads():是否还有线程在等待获得该锁
    boolean hasWaiters(Condition condition):是否有线程在等待指定的condition
    boolean isFair():是否为公平锁
    boolean isHeldByCurrentThread():判断当前线程是否持有该锁
    boolean isLocked():当前锁是否被线程(任意)持有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值