生产者消费者设计模式

生产者消费者设计模式

概述

有两个线程生产者和消费者,有一个任务队列(有大小限制,太大了阻塞当前的生产者,不让其生产)。队列中有put和take方法。

put方法时将消息(Message)放入队列中,唤醒消费者进行消费

take拿出一个消息进行消费。唤醒生产者可以生产。

代码实现如下

1.编写Message消息类

public class Message {
    private String data;

    public Message(String data) {
        this.data = data;
    }

    public String getData(){
        return this.data;
    }
}

2.创建消息队列

消息队列的take方法和put方法在出现异常时是break?还是return?

分析:个人认为在模拟代码中出现异常只能为中端此线程interrupt(),线程中断了这时不需要在put了直接返回就行了。

public class MessageQueue {
    private final LinkedList<Message> queue = new LinkedList<>();

    private static final int DEFAULT_QUEUE_SIZE = 100;

    private final int queueSize;

    public MessageQueue(){
        this(DEFAULT_QUEUE_SIZE);
    }

    public MessageQueue(int queueSize) {
        this.queueSize = queueSize;
    }

    public void put(Message message){
        synchronized (queue){
            while(queue.size() > queueSize){
                try {
                    queue.wait();
                } catch (InterruptedException e) {
                    return;
                }
            }
            queue.addLast(message);
            queue.notifyAll();
        }
    }

    public Message take(){
        synchronized (queue){
            while(queue.isEmpty()){
                try {
                    queue.wait();
                } catch (InterruptedException e) {
                    return null;
                }
            }
            Message message = queue.removeFirst();
            queue.notifyAll();
            return message;
        }
    }
}

3.模拟生产者

public class ProducerThread extends Thread {
    private final MessageQueue queue;

    private static final AtomicInteger counter = new AtomicInteger(0);

    public ProducerThread(MessageQueue queue,int seq) {
        super("producer - "+seq);
        this.queue = queue;
    }

    @Override
    public void run() {
        while(true){
            Message message = new Message(String.valueOf(counter.getAndIncrement()));
            queue.put(message);
            System.out.println(getName() + " 当前生产的数据为 : "+message.getData());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                break;
            }
        }
    }
}

4.模拟消费者

public class ConsumerThread extends Thread {
    private final MessageQueue queue;

    public ConsumerThread(MessageQueue queue,int seq) {
        super("consumer - "+seq);
        this.queue = queue;
    }

    @Override
    public void run() {
        while(true){
            Message message = queue.take();
            System.out.println(getName() + "  当前消费的数据: "+message.getData());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                break;
            }
        }
    }
}

5.测试代码

public class Application {
    private static final MessageQueue QUEUE = new MessageQueue();
    public static void main(String[] args) throws InterruptedException {
        new ConsumerThread(QUEUE,1).start();
        new ConsumerThread(QUEUE,2).start();


        Thread.sleep(2000);
        new ProducerThread(QUEUE,1).start();
        new ProducerThread(QUEUE,2).start();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值