美文网首页
生产者与消费者

生产者与消费者

作者: 努力的土豆 | 来源:发表于2020-04-01 23:50 被阅读0次

生产者与消费者问题,在计算机操作系统有详细的说明,但是书中使用的是信号量解决的。其实Java也有相似的方案解决这个问题。

public class CPTest {
    private static int in = 0;
    private static int out = 0;
    private static int[]  buffer = new int[5];
    private static Semaphore mutex = new Semaphore(1);
    private static Semaphore empty = new Semaphore(5);
    private static Semaphore full = new Semaphore(0);

    static class Procedure implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    empty.acquire();
                    mutex.acquire();
                    buffer[in] = 1;
                    in = (in + 1) % 5;
                    System.out.println(Thread.currentThread().getName());
                    System.out.println("生产了" + in + "个面包");
                    Thread.sleep(((int)Math.random())%10);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    mutex.release();
                    full.release();
                }
            }
        }
    }

    static class Consumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    full.acquire();
                    mutex.acquire();
                    buffer[out] = 0;
                    out = (out + 1) % 5;
                    System.out.println(Thread.currentThread().getName());
                    System.out.println("消费了" + out + "个面包");
                    Thread.sleep(((int)Math.random())%10);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    mutex.release();
                    empty.release();
                }
            }
        }
    }

    public static void main(String[] args) {
            new Thread(new Procedure(), "A").start();
            new Thread(new Consumer(), "B").start();
    }
}

其实,常用的wait-notify方案,但是要注意虚假唤醒,不能使用if,建议使用while

public class CPTest2 {
    private static int MAX_COUNT = 10;
    private static String LOOK = "look";
    private static int count = 0;
    private static List<Integer> list = new ArrayList<>();

    static class Procedure implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (LOOK) {
                    while (list.size() == MAX_COUNT) {
                        try {
                            System.out.println(Thread.currentThread().getName());
                            System.out.println("list is full, waiting...");
                            LOOK.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    count++;
                    list.add(count);
                    System.out.println(Thread.currentThread().getName());
                    System.out.println("生产了" + list.size() + "个面包");
                    LOOK.notifyAll();
                }
            }
        }
    }

    static class Consumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (LOOK) {
                    while (list.size() == 0) {
                        try {
                            System.out.println(Thread.currentThread().getName());
                            System.out.println("list is empty, waiting...");
                            LOOK.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    Integer integer = list.get(0);
                    list.remove(0);
                    System.out.println(Thread.currentThread().getName());
                    System.out.println("消费了一个,剩余" + list.size() + "个面包");
                    LOOK.notifyAll();
                }
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new Procedure(), "a1").start();
        new Thread(new Consumer(), "a11").start();
    }
}

相关文章

  • kafka理解

    kafka生产者、消费者与分区的分配关系 生产者如何传输到分区消费者如何从分区读取生产者、消费者与分区的关系 主题...

  • Java 并发编程——生产者与消费者

    1. 生产者与消费者 1.1 程序基本实现(问题引出) 生产者与消费者是线程操作的经典案例,即:生产者不断生产,消...

  • java多线程

    生产者与消费者问题

  • Node下的RabbitMQ应用

    一个最简单的生产者与消费者建立过程 创建生产者 创建消费者

  • 操作系统知识点持续更新

    生产者消费者问题 关于生产者消费者问题可以参考这篇文章:生产者消费者问题的java实现 临界区与互斥量 临界区:保...

  • 生产者与消费者模型

    生产者与消费者模型 通过使用Object的wait(),notify()方法进行生产者与消费者模型中出现的数据同步...

  • 2-1.死锁-经典同步问题

    三、经典同步问题 1.生产者-消费者问题 计算机系统中的许多问题都可归结为生产者与消费者问题,生产者与消费者可以通...

  • 生产者与消费者模式

    一、模式特点 生产者与消费者模式中,生产者和消费者各自做着自己的工作,生产者生产物品,将物品放入缓冲区。消费者从缓...

  • 生产者-消费者 模型

    生产者与消费者基本程序模型 在多线程开发过程之中最为著名的案例就是生产者与消费者操作,该操作的主要流程如下:生产者...

  • 生产者与消费者

    使用BlockingQueue模拟生产者与消费者

网友评论

      本文标题:生产者与消费者

      本文链接:https://www.haomeiwen.com/subject/oaazuhtx.html