• java多线程解决生产者消费者问题


    
    
    /*
    * 生产者和消费者案例
    */
    public class TestProductorAndConsumer {

    public static void main(String[] args) {
    Clerk clerk = new Clerk();

    Productor pro = new Productor(clerk);
    Consumer cus = new Consumer(clerk);

    new Thread(pro, "生产者 A").start();
    new Thread(cus, "消费者 B").start();
    }

    }

    //店员
    class Clerk{
    private int product = 0;

    //进货
    public synchronized void get(){//循环次数:0
    while(product >= 1){//为了避免虚假唤醒问题,应该总是使用在循环中
    System.out.println("产品已满!");

    try {
    this.wait();
    } catch (InterruptedException e) {
    }

    }

    System.out.println(Thread.currentThread().getName() + " : " + ++product);
    this.notifyAll();
    }

    //卖货
    public synchronized void sale(){//product = 0; 循环次数:0
    while(product <= 0){
    System.out.println("缺货!");

    try {
    this.wait();
    } catch (InterruptedException e) {
    }
    }

    System.out.println(Thread.currentThread().getName() + " : " + --product);
    this.notifyAll();
    }
    }

    //生产者
    class Productor implements Runnable{
    private Clerk clerk;

    public Productor(Clerk clerk) {
    this.clerk = clerk;
    }

    @Override
    public void run() {
    for (int i = 0; i < 20; i++) {
    try {
    Thread.sleep(200);
    } catch (InterruptedException e) {
    }

    clerk.get();
    }
    }
    }

    //消费者
    class Consumer implements Runnable{
    private Clerk clerk;

    public Consumer(Clerk clerk) {
    this.clerk = clerk;
    }

    @Override
    public void run() {
    for (int i = 0; i < 20; i++) {
    clerk.sale();
    }
    }
    }
     

    上边代码主要介绍了java多线程解决生产者消费者问题的方法,实例分析了java采用多线程的方法解决生产者消费者问题的相关技巧,需要的朋友可以参考下

    另外concurrent 包下面在执行多线程的时候也给出了特性阻塞队列 BlockingQueue   用法如下:也可以实现生产者和消费者模式

    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    
    public class Test {
        public static void main(String[] args) {
            //固定容器大小为10
            BlockingQueue<Food> foods = new LinkedBlockingQueue<Food>(10);
            Thread produce = new Thread(new Produce(foods));
            Thread consume = new Thread(new Consume(foods));
            produce.start();
            consume.start();
        }
    }
    
    /**
     * 生产者
     */
    class Produce implements Runnable {
        private BlockingQueue<Food> foods;
    
        Produce(BlockingQueue<Food> foods) {
            this.foods = foods;
        }
    
        @Override
        public void run() {
            int i = 0;
            while (i <= 10) {
                try {
                    //当生产的食品数量装满了容器,那么在while里面该食品容器(阻塞队列)会自动阻塞  wait状态 等待消费
                    foods.put(new Food("食品" + i));
                    i++;
                } catch (InterruptedException e) {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
        }
    }
    
    /**
     * 消费者
     */
    class Consume implements Runnable {
        private BlockingQueue<Food> foods;
    
        Consume(BlockingQueue<Food> foods) {
            this.foods = foods;
        }
    
        @Override
        public void run() {
            try {
                Thread.sleep(1000);  //用于测试当生产者生产满10个食品后是否进入等待状态
                while (true) {
                    //当容器里面的食品数量为空时,那么在while里面该食品容器(阻塞队列)会自动阻塞  wait状态 等待生产
                    Food food = foods.take();
                    System.out.println("消费" + food.getName());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
    }
    
    /**
     * 食品
     */
    class Food {
        private String name;
    
        String getName() {
            return name;
        }
    
        Food(String name) {
            this.name = name;
            System.out.println("生产" + name);
        }
    }
    

      

  • 相关阅读:
    Windows 批处理(bat)语法大全
    VBS基础篇 wscript 对象
    在Windows上安装和配置Jenkins
    bat批处理中截取字符串
    记事本乱码,如何修复记事本中的中文乱码
    vbs删除文件到回收站,及清空回收站
    在Windows上安装JDK8u321教程
    VBS获取硬盘序列号
    VBS调用Win32 Api函数删除文件
    VBS脚本常用经典代码收集
  • 原文地址:https://www.cnblogs.com/baizhanshi/p/5438104.html
Copyright © 2020-2023  润新知