多线程实现发布订阅升级版

一曲冷凌霜 提交于 2020-08-18 12:50:41

实际中是指定个数生产者,指定个数消费者,容器大小指定,要生产的产品个数指定的情况

场景为,生产者2个,消费者2,容器大小为5,要生产的商品数量为100

生产者类如下

/**
 * Created by yuyunbo on 2020/5/13.
 */
public class ProductObjectOne implements Runnable {
    @Override
    public void run() {
        while (true) {
            MessageVO messageVO = new MessageVO(PudConThread.hasProductTotal.get(), UUID.randomUUID().toString(), "ProductObjectOne---this is pubsub test");
            if (PudConThread.hasProductTotal.get() >= PudConThread.total) {
                System.out.println("产品已达上限,停止生产");
                return;
            }
            try {
                PudConThread.arrayBlockingQueue.put(messageVO);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            PudConThread.hasProductTotal.getAndAdd(1);
        }
    }
}
/**
 * Created by yuyunbo on 2020/5/13.
 */
public class ProductObjectTwo implements Runnable {
    @Override
    public void run() {
        while (true) {
            MessageVO messageVO = new MessageVO(PudConThread.hasProductTotal.get(), UUID.randomUUID().toString(), "ProductObjectTwo---this is pubsub test");
            if (PudConThread.hasProductTotal.get() >= PudConThread.total) {
                System.out.println("产品已达上限,停止生产");
                return;
            }
            try {
                PudConThread.arrayBlockingQueue.put(messageVO);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            PudConThread.hasProductTotal.getAndAdd(1);
        }
    }
}

消费者类如下

/**
 * Created by yuyunbo on 2020/5/13.
 */
public class ConsumerObjectOne implements Runnable {
    @Override
    public void run() {
        while (true) {
            if (PudConThread.arrayBlockingQueue.size() > 0) {
                if (PudConThread.hasConsumerTotal.get() >= PudConThread.total) {
                    System.out.println("消费者1--消费已达上限停止消费");
                    return;
                }
                /**
                 * 获取最新的一条消息消费
                 */
                try {
                    MessageVO messageVO = PudConThread.arrayBlockingQueue.take();
                    System.out.println("消费者1消费消息" + messageVO.toString());
                    PudConThread.hasConsumerTotal.getAndAdd(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
/**
 * Created by yuyunbo on 2020/5/13.
 */
public class ConsumerObjectTwo implements Runnable {
    @Override
    public void run() {
        while (true) {
            if (PudConThread.arrayBlockingQueue.size() > 0) {
                if (PudConThread.hasConsumerTotal.get() >= PudConThread.total) {
                    System.out.println("消费者2--消费已达上限停止消费");
                    return;
                }
                /**
                 * 获取最新的一条消息消费
                 */
                try {
                    MessageVO messageVO = PudConThread.arrayBlockingQueue.take();
                    System.out.println("消费者2消费消息" + messageVO.toString());
                    PudConThread.hasConsumerTotal.getAndAdd(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

主类

/**
 * Created by yuyunbo on 2020/5/13.
 */
public class PudConThread {
    public static int total = 100;
    public static volatile AtomicInteger hasProductTotal = new AtomicInteger(0);
    public static volatile AtomicInteger hasConsumerTotal = new AtomicInteger(0);
    public static final ArrayBlockingQueue<MessageVO> arrayBlockingQueue = new ArrayBlockingQueue<>(5);

    public static void main(String[] args) {
        Thread productThread1 = new Thread(new ProductObjectOne(), "P-1");
        Thread productThread2 = new Thread(new ProductObjectTwo(), "P-2");
        Thread consumerThread1 = new Thread(new ConsumerObjectOne(), "C-1");
        Thread consumerThread2 = new Thread(new ConsumerObjectTwo(), "C-2");
        consumerThread1.start();
        consumerThread2.start();
        productThread1.start();
        productThread2.start();
    }
}

执行结果如下图

有两个问题

1.两个消费者类里面的

这段日志没有打印出来

2.入下图,序号我们用的是AtomicInteger 类但是出现了重复的,理论上AtomicInteger 是CAS 的不应该重复的

以上两个问题明天晚上分析

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!