基于synchronized关键字实现的简单 生产者-消费者模型

角色

  1. 消费者:消费商店商品(Queue)
  2. 生产者:接受商家订单,把订单商品补充到商品(Queue)
  3. 商家:定期检查是否有充足的商品,发起订单(Queue)
  4. 商店:商品(Queue), 订单(Queue)

运行结果

在这里插入图片描述
在这里插入图片描述

code

Product DTO

package com.rango.jdk.cp;

import lombok.Data;

@Data
public class Product {

    private String name;
}

Consumer

package com.rango.jdk.cp;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Consumer implements Runnable {

    private Queue<Product> products;

    @Override
    public void run() {
        while (true) {
            synchronized (products) {

                if (products.isEmpty()) {
                    try {
                        System.out.println("[消费者] " + Thread.currentThread().getName() + " 等待中....");
                        products.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                Product poll = products.poll();
                if (Objects.isNull(poll)) {
                        System.out.println("[消费者] " + Thread.currentThread().getName() + " 等待中....");
                } else {
                    System.out.println("[消费者] " + Thread.currentThread().getName() + " 消费:" + poll.getName());

                    products.notifyAll();
                    try {
                        products.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        }
    }
}

Provider

package com.rango.jdk.cp;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Queue;
import java.util.concurrent.TimeUnit;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Provider implements Runnable {

    private Queue<Product> products;

    private Queue<Product> plan;

    @Override
    public void run() {
        while (true) {
            if (Seller.PLAN_NUM == 0) {
                try {
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println("[生产者] " + Thread.currentThread().getName() + " 等待商家订单");

                    continue;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            synchronized (plan) {
                if (Seller.PLAN_NUM > 0) {
                    System.out.println("[生产者] " + Thread.currentThread().getName() + " 获取到商家订单");
                }
                while (true) {
                    if (plan.size() == Seller.PLAN_NUM) {
                        synchronized (products) {
                            if (plan.size() <= 0) {
                                break;
                            }
                            while (plan.size() > 0) {
                                products.offer(plan.poll());
                            }
                            Seller.PLAN_NUM = 0;
                            System.out.println("[生产者] " + Thread.currentThread().getName() + " 完成商家订单");
                            Mail.PRODUCT_NUMBER.set(0);

                            products.notifyAll();
                            break;
                        }
                    } else {
                        try {
                            TimeUnit.MILLISECONDS.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        Product product = create(plan);
                        System.out.println("[生产者] " + Thread.currentThread().getName() + " 生产:" + product.getName());
                    }
                }
            }
        }
    }

    private Product create(Queue<Product> plan) {
        Product product = new Product();
        product.setName("商品" + Mail.PRODUCT_BATCH.get() + "-" + Mail.PRODUCT_NUMBER.incrementAndGet());
        plan.offer(product);
        return product;
    }
}

Seller

package com.rango.jdk.cp;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Queue;
import java.util.concurrent.TimeUnit;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Seller implements Runnable {

    private Queue<Product> plan;

    public static int PLAN_NUM = 0;

    @Override
    public void run() {
        while (true) {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("[商 家] 检查 PRODUCTS: " + Mail.PRODUCTS.size() + ", plan: " + plan.size() + ", PLAN_NUM: " + PLAN_NUM);
            if (Mail.PRODUCTS.size() < 5 && plan.size() == 0 && PLAN_NUM == 0) {

                PLAN_NUM = Mail.MAX_COUNT - Mail.PRODUCTS.size();
                int batch = Mail.PRODUCT_BATCH.incrementAndGet();
                System.out.println("[商 家] 发起订单,批次:" + batch + ",数量:" + PLAN_NUM);

                synchronized (plan) {
                    plan.notifyAll();
                }
            }
        }

    }
}

Mall

package com.rango.jdk.cp;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;

public class Mail {

    /**
     * 订单批次
     */
    public static volatile AtomicInteger PRODUCT_BATCH = new AtomicInteger();

    /**
     * 商品编号
     */
    public static volatile AtomicInteger PRODUCT_NUMBER = new AtomicInteger();

    /**
     * 商品最大数量
     */
    public static final int MAX_COUNT = 20;

    /**
     * 商品
     */
    public static Queue<Product> PRODUCTS = new LinkedList<>();

    /**
     * 订单计划
     */
    public static Queue<Product> PLAN = new LinkedList<>();

    public static void main(String[] args) {
        Thread p1 = new Thread(new Provider(PRODUCTS, PLAN));
        p1.setName("PROVIDER-1");
        p1.start();
        Thread p2 = new Thread(new Provider(PRODUCTS, PLAN));
        p2.setName("PROVIDER-2");
        p2.start();

        Thread c1 = new Thread(new Consumer(PRODUCTS));
        c1.setName("CONSUMER-1");
        c1.start();
        Thread c2 = new Thread(new Consumer(PRODUCTS));
        c2.setName("CONSUMER-2");
        c2.start();
        Thread c3 = new Thread(new Consumer(PRODUCTS));
        c3.setName("CONSUMER-3");
        c3.start();
        Thread s1 = new Thread(new Seller(PLAN));
        s1.setName("SELLER-1");
        s1.start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值