日常开发中,我们会经常跟日志系统打交道,日志系统算是典型的生产者消费者模型的系统。(多个不同的)生产者线程负责生产日志消息,这些系统扮演者生产者的角色,日志系统负责将消息队列里的日志上传到服务器,属于消费者角色。是一种多生产者单消费者模式的设计方式。如果生产者的生产速度大于LoggerThread
的消费速度,则BlockingDeque
线程会阻塞生产者,直到LoggerThread
有能力处理新的消息。
public class LogService {
private final BlockingQueue queue;
private final LoggerThread loggerThread;
public LogService() {
//注意队列的容量为10
queue = new LinkedBlockingQueue(10);
loggerThread = new LoggerThread();
}
public void start() {
loggerThread.start();
}
/**
* 生产者生产消息,每个log的调用者都行相当于一个生产者
*
* @param msg
* @throws InterruptedException
*/
public void log(String msg) throws InterruptedException {
queue.put(msg);
}
/**
* 消费者线程消费消息,该线程扮演的是消费者这一角色。
*/
private class LoggerThread extends Thread {
public LoggerThread(){
}
public void run() {
try {
while (true) {//无限循环
System.out.println(queue.take());
}//end while
} catch (InterruptedException e) {//在循环外响应中断
} finally {
System.out.println("log service is close");
}
}
}
}
上面代码看起来很正常,但是有如下缺点: 1、LoggerThread
没有提供关闭的方法,当没有生产者生产消息的时候,那么LoggerThread
在调用queue.take()
的时候会一直处于阻塞状态,导致JVM没法正常关闭。比如下面的调用代码,就会发生LoggerThread
无法关闭的情况。
public static void main(String[] args) {
LogService logService = new LogService();
for(int i=0;i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?