[阻塞队列]BlockingQueue来实现简易的生产消费

目录

前言:

执行结果

消费者

生产者

pojo 

main


前言:

因为同事说,可以用阻塞队列来实现生产消费,因为消费waterdrop得控制一下消费的量。

可以这样实现一个阻塞队列,不过使用线程池其实也可以的,线程池使用核心线程数来限制一下消费~后面跑跑看看效果吧。

回到正题,这个demo测出来好玩的东西

 

执行结果

首先run方法中执行到末尾,会被自动会受到,而核心线程去执行任务,这个核心线程不会销毁。生产者我这边写法是发布完就销毁掉了,跟我的使用场景有关。

   queue.offer(data, 2, TimeUnit.SECONDS)
   queue.offer(data)

这两个是有区别的,第一个是一共等两秒,放不进去再false

第二个就是放不进去直接false

比如审核通过,直接发布任务,然后执行发布。

 

Producer Thread id: 13 started!
Producer Thread id: 14 started!
Consumer Thread id: 15 started!
producer 14 put data : 2
Producer Thread id: 14end!
Producer Thread id: 14 started!
当前阻塞队列已满, 进行重试
producer 13 put data : 1
Producer Thread id: 13end!
消费taskID: 1 进行执行service
Producer Thread id: 13 started!
producer 13 put data : 4
Producer Thread id: 13end!
Producer Thread id: 13 started!
当前阻塞队列已满, 进行重试
消费taskID: 2 进行执行service
producer 14 put data : 3
Producer Thread id: 14end!
Producer Thread id: 14 started!
当前阻塞队列已满, 进行重试
当前阻塞队列已满, 进行重试
消费taskID: 4 进行执行service
消费taskID: 3 进行执行service
producer 14 put data : 6
Producer Thread id: 14end!
消费taskID: 6 进行执行service
Producer Thread id: 14 started!
producer 14 put data : 7
Producer Thread id: 14end!
Producer Thread id: 14 started!
producer 14 put data : 8
Producer Thread id: 14end!
当前阻塞队列已满, 进行重试
消费taskID: 7 进行执行service
producer 13 put data : 5
消费taskID: 8 进行执行service
Producer Thread id: 13end!
消费taskID: 5 进行执行service

 

消费者

package com.dk.learndemo.queue;

import java.util.Random;
import java.util.concurrent.BlockingQueue;

/**
 * @desc: Consumer
 * @date: 2021/3/29 3:34 下午
 */
public class Consumer implements Runnable {

    private BlockingQueue<Data> queue;

    public Consumer(BlockingQueue<Data> queue) {
        this.queue = queue;
    }


    @Override
    public void run() {
        System.out.println("Consumer Thread id: " + Thread.currentThread().getId() + " started!");
        Random r = new Random();
        while (true) {
            try {
                Data data = queue.take();
                if (data != null) {
                    //取出数据成功,输出计算平方值
                    System.out.println("消费taskID: " + data.getNum() + " 进行执行service");
                }
                //随机睡眠一定时间
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.interrupted();
            }
        }
    }
}

生产者

package com.dk.learndemo.queue;

import java.util.concurrent.BlockingQueue;

/**
 * @desc: Producer
 * @date: 2021/3/29 3:34 下午
 */
public class Producer implements Runnable {

    private volatile boolean isRunning = true;
    BlockingQueue<Data> queue;

    private volatile Integer taskId;

    private Integer maxRetryCount = 0;

    public Producer(BlockingQueue<Data> queue, Integer taskId) {
        this.queue = queue;
        this.taskId = taskId;
    }


    /**
     * 如果比如放10次或者更多次都不成功,那么则告警
     * */
    @Override
    public void run() {
        Data data = null;
        System.out.println("Producer Thread id: " + Thread.currentThread().getId() + " started!");
        try {
            while (isRunning) {
                data = new Data(taskId);
//                if (queue.offer(data, 2, TimeUnit.SECONDS)) {
                if (queue.offer(data)) {
                    //生产者向bq中添加数据
                    System.out.println(
                            "producer " + Thread.currentThread().getId() + " put data : " + data
                                    .getNum());
                    isRunning = false;
                } else if (maxRetryCount >= 5) {
                    // 超过5次都没有成功,可以进行告警
                    System.out.println(
                            "发生了告警!!! " + "Producer Thread id: " + Thread.currentThread().getId());
                    isRunning = false;
                } else {
                    System.out.println("当前阻塞队列已满, 进行重试");
                    ++maxRetryCount;
                    Thread.sleep(100);
                }
            }
            System.out.println("Producer Thread id: " + Thread.currentThread().getId() + "end!");
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.interrupted();
        }
    }

    public void stop() {
        isRunning = false;
    }
}

pojo 

package com.dk.learndemo.queue;

/**
 * @desc: Data
 * @date: 2021/3/29 3:36 下午
 */
public class Data {

    int taskId;

    public Data(int num) {
        this.taskId = num;
    }

    public Data(String str) {
        this.taskId = Integer.valueOf(str);
    }

    public int getNum() {
        return taskId;
    }
}

 

main

package com.dk.learndemo.queue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @desc: QueueMain
 * @date: 2021/3/29 3:34 下午
 */
public class QueueMain {


    /**
     * 线程池默认的拒绝策略:线程池的默认拒绝策略为AbortPolicy,即丢弃任务并抛出RejectedExecutionException异常
     * <p>
     * 这边对于生产者,只要放到了queue里面,他的生命周期就结束了,完成了他的任务
     */
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<Data> queue = new LinkedBlockingQueue<>(2);

        // 生产者也是会被销毁掉的
        ExecutorService producerExecutor = new ThreadPoolExecutor(2, 2,
                0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(10));

        // customer 假如只有两个个 永远不销毁
        ExecutorService customerExecutor = new ThreadPoolExecutor(2, 2,
                0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(10));

        Producer producer1 = new Producer(queue, 1);
        Producer producer2 = new Producer(queue, 2);
        Producer producer3 = new Producer(queue, 3);
        Producer producer4 = new Producer(queue, 4);
        Producer producer5 = new Producer(queue, 5);
        Producer producer6 = new Producer(queue, 6);
        Producer producer7 = new Producer(queue, 7);
        Producer producer8 = new Producer(queue, 8);

        // customer 永远不关闭
        Consumer consumer1 = new Consumer(queue);
        Consumer consumer2 = new Consumer(queue);

        producerExecutor.execute(producer1);
        producerExecutor.execute(producer2);
        producerExecutor.execute(producer3);
        producerExecutor.execute(producer4);
        producerExecutor.execute(producer5);
        producerExecutor.execute(producer6);
        producerExecutor.execute(producer7);
        producerExecutor.execute(producer8);

        //线程池
        customerExecutor.execute(consumer1);
//        customerExecutor.execute(consumer2);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值