前言

在这个生产者消费者模式中,生产者负责向阻塞队列中不断地添加整数值,而消费者负责从阻塞队列中不断地移除整数值。这便构成了一个非常简单的生产消费模型。下面看代码,注释很详细。

代码

1.Producer

package SimpleDemo;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.BlockingQueue;

/**
 * @author :cr
 * @date :Created in 2019/5/6 17:27
 * @description:生产者$
 * @modified By:cr
 * @version: $
 */
public class Producer implements Runnable {
    //定义阻塞队列
    private BlockingQueue<Integer> queue;
    //定义一个静态变量i用于产生队列的数据
    private static int i= 0;
    //构造器
    public Producer(BlockingQueue<Integer> queue){
        this.queue = queue;
    }
    @Override
    public void run() {
        //开始执行生产线程1
        System.out.println("["+new SimpleDateFormat("yyyy-MM-dd KK:mm:ss").format(new Date())+
                "]生产线程:"+Thread.currentThread().getId()+" 开始运行");
        try{
           for(;;){

                //如果队列已满,进入循环等待
                do{
                    Thread.sleep(1000);
                }while ((queue.size()>=BlockingSizeConstant.MAX_SIZE_OF_QUEUE));
                queue.add(i++);
                System.out.println("["+new SimpleDateFormat("yyyy-MM-dd KK:mm:ss").format(new Date())+
                        "]数据("+(i-1)+")成功加入阻塞队列");
            }
        }
        catch (Exception e){
            System.out.println("["+new SimpleDateFormat("yyyy-MM-dd KK:mm:ss").format(new Date())+"]生产线程:"+Thread.currentThread().getId()+" 已被中断");
            //发生中断异常时,直接中断当前线程
            Thread.currentThread().interrupt();
        }
    }
}

2.Customer

package SimpleDemo;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.BlockingQueue;

/**
 * @author :cr
 * @date :Created in 2019/5/6 17:37
 * @description:消费者$
 * @modified By:cr
 * @version: $
 */
public class Customer implements Runnable{
    //定义阻塞队列
    private BlockingQueue<Integer> queue;
    //构造器
    public Customer(BlockingQueue<Integer> queue){
        this.queue = queue;
    }
    @Override
    public void run() {
        //消费者线程开始执行
        System.out.println("["+new SimpleDateFormat("yyyy-MM-dd KK:mm:ss").format(new Date())+"]消费线程:"+Thread.currentThread().getId()+" 开始运行");
        try{
           for(;;){
                //如果阻塞队列为空,进入循环等待
               do{
                   Thread.sleep(1000);
               }while ((queue.size()<=0));
                System.out.println("["+new SimpleDateFormat("yyyy-MM-dd KK:mm:ss").format(new Date())+"]数据("+queue.remove()+")已被移出阻塞队列");
            }
        }
        catch (Exception e){
            System.out.println("["+new SimpleDateFormat("yyyy-MM-dd KK:mm:ss").format(new Date())+"]消费线程:"+Thread.currentThread().getId()+" 已被中断");
            //发生中断异常时,直接中断当前线程
            Thread.currentThread().interrupt();

        }
    }
}

3.Main

package SimpleDemo;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * @author :cr
 * @date :Created in 2019/5/6 17:42
 * @description:主线程(程序入口)$
 * @modified By:cr
 * @version: $
 */
public class Main {
    //定义阻塞队列
    private static BlockingQueue<Integer> queue;
    //定义线程池
    private static ExecutorService service;
    public static void main(String[] args) throws InterruptedException {
        //使用由链表构成的双向阻塞队列,容量为BlockingSizeConstant.MAX_SIZE_OF_QUEUE(值为10)
        queue = new LinkedBlockingDeque<>(BlockingSizeConstant.MAX_SIZE_OF_QUEUE);
        //使用缓存线程池
        service = Executors.newCachedThreadPool();
        //创建执行5个生产者线程
        for(int i=0;i<16;i++){
            service.execute(new Producer(queue));
        }
        //创建执行4个消费者线程
        for(int i=0;i<16;i++){
            service.execute(new Customer(queue));
        }

        Thread.sleep(5000);
        service.shutdownNow();
        System.out.println("设定的执行时间已到,线程池关闭!");
    }
}

4.BlockingSizeConstant.Class
BlockingSizeConstant类就定义了一个阻塞队列的最大容量

package SimpleDemo;
/**
 * @author :cr
 * @date :Created in 2019/5/6 18:31
 * @description:阻塞队列常量$
 * @modified By:cr
 * @version: $
 */
public class BlockingSizeConstant {
    //阻塞队列容量的最大值
    public static final int MAX_SIZE_OF_QUEUE = 10;
}

控制台输入结果

[2019-05-06 06:53:27]生产线程:14 开始运行
[2019-05-06 06:53:27]生产线程:18 开始运行
[2019-05-06 06:53:27]生产线程:25 开始运行
[2019-05-06 06:53:27]消费线程:35 开始运行
[2019-05-06 06:53:27]生产线程:28 开始运行
[2019-05-06 06:53:27]生产线程:13 开始运行
[2019-05-06 06:53:27]消费线程:29 开始运行
[2019-05-06 06:53:27]生产线程:20 开始运行
[2019-05-06 06:53:27]消费线程:42 开始运行
[2019-05-06 06:53:27]生产线程:19 开始运行
[2019-05-06 06:53:27]生产线程:23 开始运行
[2019-05-06 06:53:27]消费线程:44 开始运行
[2019-05-06 06:53:27]消费线程:37 开始运行
[2019-05-06 06:53:27]消费线程:31 开始运行
[2019-05-06 06:53:27]消费线程:40 开始运行
[2019-05-06 06:53:27]生产线程:16 开始运行
[2019-05-06 06:53:27]生产线程:27 开始运行
[2019-05-06 06:53:27]生产线程:22 开始运行
[2019-05-06 06:53:27]生产线程:24 开始运行
[2019-05-06 06:53:27]消费线程:41 开始运行
[2019-05-06 06:53:27]生产线程:17 开始运行
[2019-05-06 06:53:27]生产线程:21 开始运行
[2019-05-06 06:53:27]消费线程:34 开始运行
[2019-05-06 06:53:27]消费线程:30 开始运行
[2019-05-06 06:53:27]消费线程:36 开始运行
[2019-05-06 06:53:27]消费线程:32 开始运行
[2019-05-06 06:53:27]消费线程:38 开始运行
[2019-05-06 06:53:27]消费线程:39 开始运行
[2019-05-06 06:53:27]生产线程:26 开始运行
[2019-05-06 06:53:27]消费线程:33 开始运行
[2019-05-06 06:53:27]生产线程:15 开始运行
[2019-05-06 06:53:27]消费线程:43 开始运行
[2019-05-06 06:53:28]数据(11)成功加入阻塞队列
[2019-05-06 06:53:28]数据(12)成功加入阻塞队列
[2019-05-06 06:53:28]数据(7)已被移出阻塞队列
[2019-05-06 06:53:28]数据(10)成功加入阻塞队列
[2019-05-06 06:53:28]数据(4)已被移出阻塞队列
[2019-05-06 06:53:28]数据(12)成功加入阻塞队列
[2019-05-06 06:53:28]数据(3)成功加入阻塞队列
[2019-05-06 06:53:28]数据(1)成功加入阻塞队列
[2019-05-06 06:53:28]数据(5)成功加入阻塞队列
[2019-05-06 06:53:28]数据(0)已被移出阻塞队列
[2019-05-06 06:53:28]数据(6)已被移出阻塞队列
[2019-05-06 06:53:28]数据(9)已被移出阻塞队列
[2019-05-06 06:53:28]数据(8)已被移出阻塞队列
[2019-05-06 06:53:28]数据(15)成功加入阻塞队列
[2019-05-06 06:53:28]数据(13)成功加入阻塞队列
[2019-05-06 06:53:28]数据(10)已被移出阻塞队列
[2019-05-06 06:53:28]数据(11)已被移出阻塞队列
[2019-05-06 06:53:28]数据(9)成功加入阻塞队列
[2019-05-06 06:53:28]数据(1)已被移出阻塞队列
[2019-05-06 06:53:28]数据(13)已被移出阻塞队列
[2019-05-06 06:53:28]数据(2)成功加入阻塞队列
[2019-05-06 06:53:28]数据(2)已被移出阻塞队列
[2019-05-06 06:53:28]数据(0)成功加入阻塞队列
[2019-05-06 06:53:28]数据(5)已被移出阻塞队列
[2019-05-06 06:53:28]数据(9)成功加入阻塞队列
[2019-05-06 06:53:28]数据(5)成功加入阻塞队列
[2019-05-06 06:53:28]数据(3)已被移出阻塞队列
[2019-05-06 06:53:28]数据(14)成功加入阻塞队列
[2019-05-06 06:53:28]数据(15)成功加入阻塞队列
[2019-05-06 06:53:28]数据(15)已被移出阻塞队列
[2019-05-06 06:53:28]数据(12)已被移出阻塞队列
[2019-05-06 06:53:29]数据(16)成功加入阻塞队列
[2019-05-06 06:53:29]数据(17)成功加入阻塞队列
[2019-05-06 06:53:29]数据(14)已被移出阻塞队列
[2019-05-06 06:53:29]数据(18)成功加入阻塞队列
[2019-05-06 06:53:29]数据(19)成功加入阻塞队列
[2019-05-06 06:53:29]数据(20)成功加入阻塞队列
[2019-05-06 06:53:29]数据(16)已被移出阻塞队列
[2019-05-06 06:53:29]数据(21)成功加入阻塞队列
[2019-05-06 06:53:29]数据(22)成功加入阻塞队列
[2019-05-06 06:53:29]数据(17)已被移出阻塞队列
[2019-05-06 06:53:29]数据(18)已被移出阻塞队列
[2019-05-06 06:53:29]数据(19)已被移出阻塞队列
[2019-05-06 06:53:29]数据(20)已被移出阻塞队列
[2019-05-06 06:53:29]数据(23)成功加入阻塞队列
[2019-05-06 06:53:29]数据(21)已被移出阻塞队列
[2019-05-06 06:53:29]数据(22)已被移出阻塞队列
[2019-05-06 06:53:29]数据(24)成功加入阻塞队列
[2019-05-06 06:53:29]数据(23)已被移出阻塞队列
[2019-05-06 06:53:29]数据(24)已被移出阻塞队列
[2019-05-06 06:53:29]数据(25)成功加入阻塞队列
[2019-05-06 06:53:29]数据(26)成功加入阻塞队列
[2019-05-06 06:53:29]数据(25)已被移出阻塞队列
[2019-05-06 06:53:29]数据(28)成功加入阻塞队列
[2019-05-06 06:53:29]数据(26)已被移出阻塞队列
[2019-05-06 06:53:29]数据(29)成功加入阻塞队列
[2019-05-06 06:53:29]数据(29)成功加入阻塞队列
[2019-05-06 06:53:29]数据(27)已被移出阻塞队列
[2019-05-06 06:53:29]数据(28)已被移出阻塞队列
[2019-05-06 06:53:29]数据(29)已被移出阻塞队列
[2019-05-06 06:53:29]数据(30)成功加入阻塞队列
[2019-05-06 06:53:29]数据(31)成功加入阻塞队列
[2019-05-06 06:53:29]数据(30)已被移出阻塞队列
[2019-05-06 06:53:30]数据(32)成功加入阻塞队列
[2019-05-06 06:53:30]数据(31)已被移出阻塞队列
[2019-05-06 06:53:30]数据(33)成功加入阻塞队列
[2019-05-06 06:53:30]数据(34)成功加入阻塞队列
[2019-05-06 06:53:30]数据(37)成功加入阻塞队列
[2019-05-06 06:53:30]数据(32)已被移出阻塞队列
[2019-05-06 06:53:30]数据(37)成功加入阻塞队列
[2019-05-06 06:53:30]数据(37)成功加入阻塞队列
[2019-05-06 06:53:30]数据(38)成功加入阻塞队列
[2019-05-06 06:53:30]数据(33)已被移出阻塞队列
[2019-05-06 06:53:30]数据(34)已被移出阻塞队列
[2019-05-06 06:53:30]数据(36)已被移出阻塞队列
[2019-05-06 06:53:30]数据(37)已被移出阻塞队列
[2019-05-06 06:53:30]数据(39)成功加入阻塞队列
[2019-05-06 06:53:30]数据(35)已被移出阻塞队列
[2019-05-06 06:53:30]数据(38)已被移出阻塞队列
[2019-05-06 06:53:30]数据(40)成功加入阻塞队列
[2019-05-06 06:53:30]数据(39)已被移出阻塞队列
[2019-05-06 06:53:30]数据(40)已被移出阻塞队列
[2019-05-06 06:53:30]数据(41)成功加入阻塞队列
[2019-05-06 06:53:30]数据(42)成功加入阻塞队列
[2019-05-06 06:53:30]数据(41)已被移出阻塞队列
[2019-05-06 06:53:30]数据(43)成功加入阻塞队列
[2019-05-06 06:53:30]数据(42)已被移出阻塞队列
[2019-05-06 06:53:30]数据(44)成功加入阻塞队列
[2019-05-06 06:53:30]数据(45)成功加入阻塞队列
[2019-05-06 06:53:30]数据(43)已被移出阻塞队列
[2019-05-06 06:53:30]数据(44)已被移出阻塞队列
[2019-05-06 06:53:30]数据(47)成功加入阻塞队列
[2019-05-06 06:53:30]数据(47)成功加入阻塞队列
[2019-05-06 06:53:30]数据(45)已被移出阻塞队列
[2019-05-06 06:53:30]数据(46)已被移出阻塞队列
[2019-05-06 06:53:31]数据(48)成功加入阻塞队列
[2019-05-06 06:53:31]数据(49)成功加入阻塞队列
[2019-05-06 06:53:31]数据(47)已被移出阻塞队列
[2019-05-06 06:53:31]数据(50)成功加入阻塞队列
[2019-05-06 06:53:31]数据(48)已被移出阻塞队列
[2019-05-06 06:53:31]数据(53)成功加入阻塞队列
[2019-05-06 06:53:31]数据(53)成功加入阻塞队列
[2019-05-06 06:53:31]数据(53)成功加入阻塞队列
[2019-05-06 06:53:31]数据(54)成功加入阻塞队列
[2019-05-06 06:53:31]数据(49)已被移出阻塞队列
[2019-05-06 06:53:31]数据(50)已被移出阻塞队列
[2019-05-06 06:53:31]数据(51)已被移出阻塞队列
[2019-05-06 06:53:31]数据(52)已被移出阻塞队列
[2019-05-06 06:53:31]数据(55)成功加入阻塞队列
[2019-05-06 06:53:31]数据(54)已被移出阻塞队列
[2019-05-06 06:53:31]数据(53)已被移出阻塞队列
[2019-05-06 06:53:31]数据(56)成功加入阻塞队列
[2019-05-06 06:53:31]数据(55)已被移出阻塞队列
[2019-05-06 06:53:31]数据(57)成功加入阻塞队列
[2019-05-06 06:53:31]数据(56)已被移出阻塞队列
[2019-05-06 06:53:31]数据(58)成功加入阻塞队列
[2019-05-06 06:53:31]数据(59)成功加入阻塞队列
[2019-05-06 06:53:31]数据(57)已被移出阻塞队列
[2019-05-06 06:53:31]数据(58)已被移出阻塞队列
[2019-05-06 06:53:31]数据(60)成功加入阻塞队列
[2019-05-06 06:53:31]数据(61)成功加入阻塞队列
[2019-05-06 06:53:31]数据(59)已被移出阻塞队列
[2019-05-06 06:53:31]数据(62)成功加入阻塞队列
[2019-05-06 06:53:31]数据(61)已被移出阻塞队列
[2019-05-06 06:53:31]数据(60)已被移出阻塞队列
[2019-05-06 06:53:31]数据(62)已被移出阻塞队列
[2019-05-06 06:53:31]数据(63)成功加入阻塞队列
设定的执行时间已到,线程池关闭!
[2019-05-06 06:53:31]生产线程:26 已被中断
[2019-05-06 06:53:31]消费线程:30 已被中断
[2019-05-06 06:53:31]消费线程:39 已被中断
[2019-05-06 06:53:31]生产线程:19 已被中断
[2019-05-06 06:53:31]消费线程:40 已被中断
[2019-05-06 06:53:31]消费线程:42 已被中断
[2019-05-06 06:53:31]生产线程:25 已被中断
[2019-05-06 06:53:31]消费线程:44 已被中断
[2019-05-06 06:53:31]消费线程:29 已被中断
[2019-05-06 06:53:31]生产线程:13 已被中断
[2019-05-06 06:53:31]消费线程:35 已被中断
[2019-05-06 06:53:31]消费线程:38 已被中断
[2019-05-06 06:53:31]生产线程:22 已被中断
[2019-05-06 06:53:31]生产线程:15 已被中断
[2019-05-06 06:53:31]生产线程:18 已被中断
[2019-05-06 06:53:31]消费线程:31 已被中断
[2019-05-06 06:53:31]消费线程:41 已被中断
[2019-05-06 06:53:31]消费线程:34 已被中断
[2019-05-06 06:53:31]生产线程:24 已被中断
[2019-05-06 06:53:31]消费线程:43 已被中断
[2019-05-06 06:53:31]生产线程:27 已被中断
[2019-05-06 06:53:31]消费线程:36 已被中断
[2019-05-06 06:53:31]生产线程:23 已被中断
[2019-05-06 06:53:31]消费线程:32 已被中断
[2019-05-06 06:53:31]生产线程:20 已被中断
[2019-05-06 06:53:31]消费线程:37 已被中断
[2019-05-06 06:53:31]生产线程:14 已被中断
[2019-05-06 06:53:31]生产线程:17 已被中断
[2019-05-06 06:53:31]生产线程:16 已被中断
[2019-05-06 06:53:31]生产线程:21 已被中断
[2019-05-06 06:53:31]消费线程:33 已被中断
[2019-05-06 06:53:31]生产线程:28 已被中断

Process finished with exit code 0