【JAVA并发编程实战】7、日志服务
这里是一个应用项目使用生产消费模型的日志类
package cn.study.concurrency; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import org.junit.Test; /**
* 日志服务
* @author xiaof
*
*/
public class LogWriter {
private final BlockingQueue<String> queue;
private final LoggerThread logger;
private final static int CAPACITY = 500;
private boolean isShutdown; //停止线程 public LogWriter()
{
this.queue = new LinkedBlockingQueue<String>(CAPACITY);
this.logger = new LoggerThread();
} public void start()
{
//判断这个线程是否已经启动
if(!logger.isAlive())
{
logger.start();
}
} public void log(String msg) throws InterruptedException
{
//放入日志队列并阻塞队列
if(!isShutdown)
queue.put(msg);
else
throw new IllegalStateException("日志开关没有打开");
} public boolean isShutdown() {
return isShutdown;
} public void setShutdown(boolean isShutdown) {
this.isShutdown = isShutdown;
} private class LoggerThread extends Thread
{
public void run()
{
try
{
while(true)
{
//从队列中取出队列头数据,并输出,有必要并阻塞队列
System.out.println("这是日志:" + queue.take());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
} @Test
public void test()
{
LogWriter log = new LogWriter();
log.start();
int i = 1;
while(true)
{
try {
Thread.currentThread().sleep(2000);
//把日志放入队列
log.log("这是日志:" + i++); if(i == 3)
{
log.setShutdown(true);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }
更加可靠的取消日志服务的操作
package cn.study.concurrency; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import org.junit.Test; /**
* 日志类添加可靠的取消操作
* @author xiaof
*
*/
public class LogService {
private final BlockingQueue<String> queue;
private final LoggerThread loggerThread;
private boolean isShutdown;
//如果线程停止提交任务,线程不能停,先得吧剩余的任务提交结束
private int reservations;
private final static int CAPACITY = 500; public LogService()
{
//队列长度
this.queue = new LinkedBlockingQueue<String>(CAPACITY);
this.loggerThread = new LoggerThread();
} public void start()
{
//判断这个线程是否已经启动
if(!loggerThread.isAlive())
{
loggerThread.start();
}
} public void log(String msg) throws InterruptedException
{
//放入日志队列并阻塞队列
synchronized(this)
{
if(isShutdown)
throw new IllegalStateException("日志开关没有打开");
++reservations;
}
queue.put(msg);
} public void stop()
{
synchronized(this)
{
isShutdown = true;
}
//中断线程
loggerThread.interrupt();
} private class LoggerThread extends Thread
{
public void run()
{
try
{
while(true)
{
try
{
//对日志类上锁
synchronized(LogService.this)
{
if(isShutdown && reservations == 0)
{
break;//停止线程
}
}
//取出日志信息
String msg = queue.take();
//提交成功一条,对阻塞的数据计数减少一条
synchronized(LogService.this)
{
--reservations;
}
System.out.println(msg);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
finally
{
System.out.println("日志结束..........");
}
}
} @Test
public void test()
{
LogService log = new LogService();
log.start();
int i = 1;
while(true)
{
try {
Thread.currentThread().sleep(2000);
//把日志放入队列
log.log("这是日志:" + i++); if(i == 3)
{
log.stop();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
【JAVA并发编程实战】7、日志服务的更多相关文章
- Java并发编程实战---第六章:任务执行
废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...
- 《java并发编程实战》笔记
<java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为: Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...
- 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结
<Java并发编程实战>和<Java并发编程的艺术> Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...
- 《Java并发编程实战》文摘
更新时间:2017-06-03 <Java并发编程实战>文摘,有兴趣的朋友可以买本纸质书仔细研究下. 一 线程安全性 1.1 什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何 ...
- Java并发编程实战——读后感
未完待续. 阅读帮助 本文运用<如何阅读一本书>的学习方法进行学习. P15 表示对于书的第15页. Java并发编程实战简称为并发书或者该书之类的. 熟能生巧,不断地去理解,就像欣赏一部 ...
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
- 【Java并发编程实战】-----“J.U.C”:CyclicBarrier
在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...
随机推荐
- WCF服务的异常消息
原创地址:http://www.cnblogs.com/jfzhu/p/4055024.html 转载请注明出处 WCF Service发生异常的时候,客户端一般只能看见这样一个错误:“The ser ...
- Hadoop 裡的 fsck 指令
Hadoop 裡的 fsck 指令,可檢查 HDFS 裡的檔案 (file),是否有 corrupt (毀損) 或資料遺失,並產生 HDFS 檔案系統的整體健康報告.報告內容,包括:Total blo ...
- 修改注册表 去除Windows快捷方式图标小箭头
一些朋友不喜欢Windows系统中快捷方式图标上面的小箭头,下面介绍如何修改注册表去除快捷方式图标上的小箭头. 1.开始->运行->输入regedit,启动注册表编辑器,然后; 2.依次展 ...
- Java 浅析三大特性之一封装
在说Java 三个特性之前,我们先了解一下什么是面向对象,以及为什么Java是面向对象的语言. 面向对象是区别于面向过程的一种编程的思想.我们可以通过这个例子冰箱装大象的例子来了解一下面向对象与面向过 ...
- Thrift架构~目录
回到占占推荐博客索引 概念相关 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ru ...
- Java抽象类的总结
什么是抽象类: 当你在定义一个父级的类的时候,往往在父级内的方法没有添加任何内容,这时候如果你在子类里面调用父级的时候,万一在子类之中类名或者方法名没有写正确,会出现不执行的情况,但是这种情况默认是不 ...
- 基于ReactCSSTransitionGroup实现react-router过渡动画
此前,我使用了react-router库来完成单页应用的路由,从而实现组件之间的切换能力.然而,默认页面的切换是非常生硬的,为了让页面切换更加缓和与舒适,通常的方案就是过渡动画. 这里我调研了2种 ...
- 【转】C#调用Windows图片和传真查看器打开图片
//建立新的系统进程 System.Diagnostics.Process process = new System.Diagnostics.Process(); //设置文件名,此处为图片的真实路径 ...
- 【原创】开源Math.NET基础数学类库使用(04)C#解析Matrix Marke数据格式
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
- javascript中异步和闭包产生的困惑
这里我不打算大谈特谈什么是异步,什么是闭包,这些内容在博客园都已经写的够多的了,但是这些内容出现的多,并不代表所有初学者都已经撑握了,所以我还是打算,用一个比较常见的示例来分析一下,或许能让对这个问题 ...