Java 并发编程—— Lock 和 Condition

  • “==Cnt:” + i);
    }
    lock.unlock();
    }
    }
    }

2. Condition 源码分析

在上面我们介绍 Lock 类时,有一个 newCondition 方法:

/**

  • 返回一个绑定到Lock对象上的Condition实例,在获取condition对象前,当前线程
  • 必须持有对应的lock对象。
    */
    Condition newCondition();

从这里可以猜想到一个 Lock 中应该绑定一个 Condition 对象。ConditionJava 提供用来实现等待/通知的类。

我们知道 Object 对象提供了 waitwaitAllnotifynotifyAll 的方法用来实现线程的同步、等待和唤醒。但 Condition 类提供了比 wait/notify 更丰富的功能,Condition 对象由 lock 对象所创建的,同时一个 Lock 可以创建多个 Condition 对象,即创建多个对象监听器,这样就可以指定唤醒具体线程,而 notify 是随机唤醒线程。

public interface Condition {

/**

  • 造成当前线程在接到信号或被 中断之前一直处于等待状态。
  • @throws InterruptedException if the current thread is interrupted
  •     (and interruption of thread suspension is supported)
    

*/
void await() throws InterruptedException;

/**

  • 造成当前线程在接到信号或被 中断之前一直处于等待状态。
    */
    void awaitUninterruptibly();

/**

  • 使当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  • @param nanosTimeout the maximum time to wait, in nanoseconds
  • @return an estimate of the {@code nanosTimeout} value minus
  •     the time spent waiting upon return from this method.
    
  •     A positive value may be used as the argument to a
    
  •     subsequent call to this method to finish waiting out
    
  •     the desired time.  A value less than or equal to zero
    
  •     indicates that no time remains.
    
  • @throws InterruptedException if the current thread is interrupted
  •     (and interruption of thread suspension is supported)
    

*/
long awaitNanos(long nanosTimeout) throws InterruptedException;

/**

  • 使当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  • @param time the maximum time to wait
  • @param unit the time unit of the {@code time} argument
  • @return {@code false} if the waiting time detectably elapsed
  •     before return from the method, else {@code true}
    
  • @throws InterruptedException if the current thread is interrupted
  •     (and interruption of thread suspension is supported)
    

*/
boolean await(long time, TimeUnit unit) throws InterruptedException;

/**

  • 唤醒一个等待线程。
    */
    void signal();

/**

  • 唤醒所有等待线程。
    */
    void signalAll();
    }

通过上面的源码注释能看到,Condition 提供了以下方法:

  • void await():造成当前线程在接到信号或被中断之前一直处于等待状态。
  • boolean await(long time, TimeUnit unit):造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  • long awaitNanos(long nanosTimeout):造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
  • void awaitUninterruptibly():造成当前线程在接到信号之前一直处于等待状态。
  • boolean awaitUntil(Date deadline):造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。
  • void signal():唤醒一个等待线程。
  • void signalAll():唤醒所有等待线程。

在实际开发中,通过 await 方法进行线程的等待,signal 进行唤醒。注意,Condition 实例只是一些普通的对象,它们自身可以用作 synchronized 语句中的目标,并且可以调用自己的 waitnotification 监视器方法。

3. 生产者消费者示例

/**

  • 实现生产消费者的例子
  • 要求:
  • 有两股力量:生产和消费
  • 当仓库生产满了的时候就要通知消费者进行消费,并且停止生产
  • 当仓库空的时候,消费者要通知生产者进行生产,并且停止消费
  • 其它情况,正常生产、消费。
  • 生产者与消费者模型中,要保证以下几点:
  • 1 同一时间内只能有一个生产者生产
  • 2 同一时间内只能有一个消费者消费
  • 3 共享空间空时消费者不能继续消费
  • 4 共享空间满时生产者不能继续生产
  • @author mr_dsw
    */
    public class ConcrateDemo {
    public static void main(String []args){
    Resource resource = new Resource();
    ProduceThread produceThread = new ProduceThread(resource);
    ConsumeThread consumeThread = new ConsumeThread(resource);
    //四个生产者
    new Thread(produceThread).start();
    new Thread(produceThread).start();
    new Thread(produceThread).start();
    new Thread(produceThread).start();
    //四个消费者
    new Thread(consumeThread).start();
    new Thread(consumeThread).start();
    new Thread(consumeThread).start();
    new Thread(consumeThread).start();
    }
    }

class Resource{
private final int MAX_SIZE = 10;
private LinkedList list = new LinkedList();
private Lock lock = new ReentrantLock();
private Condition fullCondition = lock.newCondition();
private Condition emptyCondition = lock.newCondition();

/**

  • 生产物品,存在多个生产者
    */
    public void produce(){
    //如果生产满了,则就唤醒消费者
    lock.lock();
    while(list.size() == MAX_SIZE){
    System.out.println(“生产满了,暂时无法生产:” + list.size());
    emptyCondition.signal();
    try {
    fullCondition.await();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    list.add(new Object());
    System.out.println(Thread.currentThread().getName() + “生产新产品,共有:” + list.size());
    lock.unlock();
    }

/**

  • 消费者,存在多个消费者
    */
    public void consume(){
    lock.lock();
    while(list.size() == 0){
    System.out.println(“没有物品了,需要通知生产了”);
    fullCondition.signal();
    try {
    emptyCondition.await();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    System.out.println(Thread.currentThread().getName() + “消费产品,共有:” + list.size());
    list.remove();
    lock.unlock();
    }
    }

class ProduceThread implements Runnable{
private Resource resource;

public ProduceThread(Resource resource){
this.resource = resource;
}

public void run() {
for(;😉
resource.produce();
}
}

最后

分享一些系统的面试题,大家可以拿去刷一刷,准备面试涨薪。

这些面试题相对应的技术点:

  • JVM
  • MySQL
  • Mybatis
  • MongoDB
  • Redis
  • Spring
  • Spring boot
  • Spring cloud
  • Kafka
  • RabbitMQ
  • Nginx

大类就是:

  • Java基础
  • 数据结构与算法
  • 并发编程
  • 数据库
  • 设计模式
  • 微服务
  • 消息中间件

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

程序员,每个月给你发多少工资,你才会想老板想的事?

179129)]

[外链图片转存中…(img-QLWL96Xx-1714314179130)]

[外链图片转存中…(img-UvjrJTeI-1714314179130)]

[外链图片转存中…(img-O7IQGzNp-1714314179130)]

[外链图片转存中…(img-PHjXRud0-1714314179131)]

[外链图片转存中…(img-SXUBp496-1714314179131)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值