ReentrantLock学习(一)ReentrantLock的使用

一、例子

  • 一段简单的使用ReentrantLock的例子
public class ReentrantLockMain {

    static String workContent = null;

    public static void main(String[] args) throws InterruptedException {

        //new一个锁
        Lock lock = new ReentrantLock();
        //生成一个condition
        Condition condition = lock.newCondition();

        //开启子线程小T
        new Thread(() -> {
            lock.lock();
            try {
                String name = Thread.currentThread().getName();
                System.out.println(name+":我获取到锁了,开始工作了");
                if(workContent == null){
                    System.out.println(name+":M夫人还没布置工作啊,等等吧");
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(name+":收到M夫人的工作【"+ workContent +"】, 很快我就做完了");
            }finally {
                lock.unlock();
            }
        },"子线程小T").start();
        Thread.sleep(1000);
        System.out.println(">>>>>>>>>>>>>>>10秒后M夫人驾到<<<<<<<<<<<<<<");
        Thread.sleep(10000);

        //主线程获取锁
        lock.lock();
        try{
            //获取到锁
            System.out.println("M夫人:我获取到锁,开始布置任务");
            workContent = "秘密任务:找bug";
            System.out.println("M夫人:任务布置完成,叫【子线程小T】来做");
            condition.signal();
        }finally {
            lock.unlock();
        }
    }
}
  • 代码执行结果  
子线程小T:我获取到锁了,开始工作了
子线程小T:M夫人还没布置工作啊,等等吧
>>>>>>>>>>>>>>>10秒后M夫人驾到<<<<<<<<<<<<<<
M夫人:我获取到锁,开始布置任务
M夫人:任务布置完成,叫【子线程小T】来做
子线程小T:收到M夫人的工作【秘密任务:找bug】, 很快我就做完了

二、 锁使用说明

  • new ReentrantLock() 

创建一个lock,在其内部其实是创建了一个NonfairSync对象赋值给锁的sync变量。此处为非公平锁。

  • lock.newCondition()

创建一个Condition,在其内部实际为调用了sync的newCondition方法,而再内部实际为new ConditionObject()。(此处有知识点) 

  • lock.lock()

获取锁,为阻塞式的,此处非公平锁的话。(之后单说公平锁与非公平锁代码上实现的具体区别)

  • condition.await()

比较像synchronized中使用wait,但是condition.await()比较灵活,一个锁可以设置多个condition 

  • condition.signal()

 比较像synchronized中使用notify,同样,condition.signal()也可以是多个condition,比较灵活

  • lock.unlock() 

释放锁资源,此处使用的锁状态实际为占有锁的一个计数器,同时唤起下一等待线程(sync队列节点里记录了)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ReentrantLock是Java中的一个可重入锁,它提供了与synchronized关键字类似的功能,但更加灵活和强大。下面是ReentrantLock使用介绍: 1. 创建ReentrantLock对象: ```java ReentrantLock lock = new ReentrantLock(); ``` 2. 获取锁: ```java lock.lock(); // 获取锁,如果锁已被其他线程持有,则当前线程会被阻塞,直到获取到锁为止 ``` 3. 释放锁: ```java lock.unlock(); // 释放锁,如果当前线程持有锁,则释放锁;如果当前线程没有持有锁,则会抛出IllegalMonitorStateException异常 ``` 4. 使用try-finally确保锁的释放: ```java lock.lock(); try { // 执行需要同步的代码块 } finally { lock.unlock(); // 在finally块中释放锁,确保锁的释放 } ``` 5. 使用条件变量: ```java Condition condition = lock.newCondition(); // 创建条件变量 condition.await(); // 当前线程等待,直到其他线程调用signal或signalAll方法唤醒它 condition.signal(); // 唤醒一个等待的线程 condition.signalAll(); // 唤醒所有等待的线程 ``` 6. 公平锁和非公平锁: ReentrantLock可以是公平锁或非公平锁,默认情况下是非公平锁。在构造ReentrantLock对象时,可以传入一个boolean参数来指定是否使用公平锁: ```java ReentrantLock lock = new ReentrantLock(true); // 使用公平锁 ReentrantLock lock = new ReentrantLock(false); // 使用非公平锁 ``` 7. 其他方法: - `isHeldByCurrentThread()`:判断当前线程是否持有锁。 - `getHoldCount()`:获取当前线程持有锁的次数。 - `getQueueLength()`:获取等待获取锁的线程数。 - `hasQueuedThreads()`:判断是否有线程在等待获取锁。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值