Java Condition,消费者、生产者、消息队列 实践二

本文通过一个Java示例展示了如何使用Condition实现生产者消费者模型。消费者线程在队列为空时等待,生产者线程在队列满时等待。当条件满足时,线程被唤醒继续执行,确保资源的有效利用。此模型展示了线程间的同步与通信机制。
摘要由CSDN通过智能技术生成

Condition:

void await() :造成当前线程在接到信号或被中断之前一直处于等待状态。
void await(long time, TimeUnit unit) :造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态
long awaitNanos(long nanosTimeout) :造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。返回值表示剩余时间,如果在nanosTimesout之前唤醒,那么返回值 = nanosTimeout - 消耗时间,如果返回值 <= 0 ,则可以认定它已经超时了。
void awaitUninterruptibly() :造成当前线程在接到信号之前一直处于等待状态。【注意:该方法对中断不敏感】。
boolean awaitUntil(Date deadline) :造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。如果没有到指定时间就被通知,则返回true,否则表示到了指定时间,返回返回false。
void signal() :唤醒一个等待线程。该线程从等待方法返回前必须获得与Condition相关的锁。
void signalAll() :唤醒所有等待线程。能够从等待方法返回的线程必须获得与Condition相关的锁。

消费者:

public class Consumer implements Runnable{
    private Queue<String> messageQueue;
    private Lock lock;
    private Condition condition;

    public Consumer(Queue<String> messageQueue, Lock lock, Condition condition) {
        this.messageQueue = messageQueue;
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        int i=0;
        while(true){
            i++;
            lock.lock();
            while(messageQueue.isEmpty()){
                System.out.println("消费者队列空了,先等待");
                try {
                    condition.await(); // 阻塞当前线程并释放锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("消费者消息"+i+":"+ messageQueue.remove());
            condition.signal(); //唤醒一个阻塞的线程
            lock.unlock();
        }
    }
}

生产者:

public class Producer implements Runnable {

    private Queue<String> msg;
    private int maxSize;
    private Lock lock;
    private Condition condition;

    public Producer(Queue<String> msg, int maxSize, Lock lock, Condition condition) {
        this.msg = msg;
        this.maxSize = maxSize;
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        int i = 0;
        while (true) {
            i++;
            lock.lock();
            while (msg.size() == maxSize) {
                System.out.println("生产者队列满了,先等待");
                try {
                    condition.await(); // 阻塞当前线程并释放锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            String message = "消息" + i;
            System.out.println("生产者生产消息:" + message);
            msg.add(message);
            condition.signal(); //唤醒一个阻塞的线程
            lock.unlock();
        }
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
        Lock lock = new ReentrantLock(); //重入锁
        Condition condition = lock.newCondition();
        int maxSize = 5;
        Producer producer = new Producer(queue, maxSize, lock, condition);
        Consumer consumer = new Consumer(queue, lock, condition);

        Thread producerThread = new Thread(producer);
        Thread consumerThread = new Thread(consumer);
        producerThread.start();
        consumerThread.start();
    }
}

结果:

消费者队列空了,先等待
生产者生产消息:消息1
生产者生产消息:消息2
生产者生产消息:消息3
生产者生产消息:消息4
生产者生产消息:消息5
生产者队列满了,先等待
消费者消息1:消息1
消费者消息2:消息2
消费者消息3:消息3
消费者消息4:消息4
消费者消息5:消息5
消费者队列空了,先等待
生产者生产消息:消息6
...

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风铃峰顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值