amanxu

      本文借助于(https://zm12.sm-tc.cn/?src=l4uLj8XQ0I2QnZqNi9KImpbRlouahprRnJCS0J2TkJjQzc%2FNx83Izw%3D%3D&from=derive&depth=2&v=1&link_type=230&uid=826acdfbc57d0064209d00a78763d87e&hid=71cdfa0523bc399b78ee40258b6f7d6f&restype=1&uc_param_str=dnntnwvepffrgibijbprsvdsdichei&query=Java+%E7%94%9F%E4%BA%A7%E8%80%85%E6%B6%88%E8%B4%B9%E8%80%85%E6%A8%A1%E5%9E%8B)该博客进行学习,并做了扩展和修改;

      Java中生产者和消费者模式主要体现的是多线程环境下对共享数据的访问,主要技术就是同步、wait()和notify(),其中notify()和notifyAll()必须在同步带模块中执行。

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 典型的生产者消费者模式
 * @Company: Shanghai COS Software <br>
 * @Copyright: Copyright (c)2017 <br>
 * @author niexx <br>
 * @Date 2017年8月17日 下午10:47:10 <br>
 * @version 1.0 <br>
 */
public class ProduceAndConsume {

    private List<String> queue = new ArrayList<String>();
    private int max_num = 20;
    private int min_num = 1;
    private int curSize;

    public synchronized String getMessage() throws InterruptedException {
        // 此处要使用while不能使用if,否则当消费者多于生产者时将报错(java.lang.IndexOutOfBoundsException)
        while (queue.size() < min_num) {
            wait();
        }
        String message = queue.remove(0);
        curSize = queue.size();
        notifyAll();
        return message;
    }

    public synchronized void putMessage(String message) throws InterruptedException {
        while (queue.size() >= max_num) {// 此处要使用while不能使用if,否则当生产者多于消费者时库存限制将无效
            wait();// 使用while当线程被唤醒时,先通过循环判断是否满足while,如果满足继续wait();如果使用if,当线程被唤醒时获得锁后直接执行后面代码不会判断当前队列中的数量,

                    //无法实现库存限制
        }

        queue.add(message);
        curSize = queue.size();
        notifyAll();
    }

    public List<String> getQueue() {
        return queue;
    }

    public void setQueue(List<String> queue) {
        this.queue = queue;
    }

    public static void main(String[] args) {
        ProduceAndConsume queue = new ProduceAndConsume();
        new Thread(new MessageProducer("生产者1", queue)).start();
        new Thread(new MessageProducer("生产者2", queue)).start();
        new Thread(new MessageProducer("生产者3", queue)).start();
        new Thread(new MessageProducer("生产者4", queue)).start();
        new Thread(new MessageProducer("生产者5", queue)).start();
        new Thread(new MessageProducer("生产者6", queue)).start();
        new Thread(new MessageConsumer("消费者1", queue)).start();
        new Thread(new MessageConsumer("消费者2", queue)).start();
        // new Thread(new MessageConsumer("消费者3", queue)).start();
        // new Thread(new MessageConsumer("消费者4", queue)).start();
        // new Thread(new MessageConsumer("消费者5", queue)).start();
        // new Thread(new MessageConsumer("消费者6", queue)).start();
    }
}

class MessageProducer implements Runnable {

    private ProduceAndConsume queue;

    private String name;

    public MessageProducer(String name, ProduceAndConsume queue) {
        super();
        this.queue = queue;
        this.name = name;
    }

    public void run() {
        int i = 0;
        while (true) {
            i++;
            try {
                Thread.sleep(500);
                queue.putMessage("===" + name + "===生产了第" + i + "产品!");
                System.out.println("===" + name + "===生产了第" + i + "个产品");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

}

class MessageConsumer implements Runnable {

    private ProduceAndConsume queue;

    private String name;

    public MessageConsumer(String name, ProduceAndConsume queue) {
        this.queue = queue;
        this.name = name;
    }

    public void run() {
        try {
            while (true) {
                Thread.sleep(500);
                System.out.println(name + "===消费了:" + queue.getMessage() + "--剩余库存--" + queue.getQueue().size());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

分类:

技术点:

相关文章: