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