生产者消费者模型与多线程

本文介绍了生产者消费者模型的问题和解决方案,通过引入阻塞队列来降低两者之间的耦合。在多线程环境下,使用wait()、notify()和notifyAll()方法协调生产者和消费者的活动。文章还提到了Thread.sleep()和wait()的区别,并展示了使用AtomicInteger确保线程安全的代码示例。
摘要由CSDN通过智能技术生成

生产者生产商品,消费者进行消费在这个过程中有一个强耦合问题,消费者有需求时可能生产者并没有生产;为了解决这个问题在生产者和消费者之间加入一个阻塞队列,先通知生产者生产一定库存,然后进入等待当消费者消费完后消费者等待生产者再次工作;
在这里插入图片描述
在多线程中要达到这个目的就要借助wait()和notify()这两个属于Object类的方法,线程中的sleep()和wait()有着很大区别;
sleep()是Thread类中定义的方法,到了一定的时间后该线程自动唤醒,不会释放对象锁。
wait()是Object类中定义的方法,要想唤醒必须使用notify()、notifyAll()方法才能唤醒,会释放对象锁;
下面就是生产者消费者模型代码

class Goods {
    private final String name;

    Goods(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Producer implements Runnable {
    private final Queue<Goods> goods;
    private final Object monitor;
    private final AtomicInteger atomicInteger;

    Producer(Queue<Goods> goods, Object monitor, AtomicInteger atomicInteger) {
        this.goods = goods;
        this.monitor = monitor;
        this.atomicInteger = atomicInteger;
    }


    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (monitor) {
                if (this.goods.size() >= 10) {
                    try {
                        this.monitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    Goods good = new Goods("商品" + atomicInteger.getAndAdd(1));
                    goods.add(good);
                    System.out.println("生产者生产商品:" + good);
                }
            }
        }
    }
}

class Customer implements Runnable {
    private final Queue<Goods> goods;
    private final Object monitor;

    Customer(Queue<Goods> goods, Object monitor) {
        this.goods = goods;
        this.monitor = monitor;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (monitor) {
                if (goods.isEmpty()) {
                    this.monitor.notify();
                } else {
                    Goods g = goods.poll();
                    System.out.println("消费者消费: " + g);
                }
            }
        }
    }
}

在Producer类中用到了一个叫做AtomicInteger的类,如果同一个数据不做处理被多线程同时访问肯定会发生错误,此时就有两种方法可以避免一个是利用同步块,另一个就是运用这个类进行线程安全的加减操作;
测试类:

public class ProductToCustomer {
    public static void main(String[] args) {
        Queue<Goods> n = new LinkedList<>();
        Object o = new Object();
        Producer producer = new Producer(n, o, new AtomicInteger(1));
        Customer customer = new Customer(n, o);
        Thread start = new Thread(producer, "生产者");
        Thread end = new Thread(customer, "消费者");
        end.start();
        start.start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值