这里是一个应用项目使用生产消费模型的日志类

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();
}
}
}
}

最新文章

  1. WebApi跨域问题
  2. WPF中的动画——(三)时间线(TimeLine)
  3. Linux与user和group相关文件分析
  4. 网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程
  5. 一道打印M的面试题
  6. 课堂笔记--Strom并发模型
  7. 文件I/O操作(2)
  8. unity3d游戏开发——新手引导
  9. 【转帖】C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用
  10. STL: generate ,geterate_n
  11. Java 自定义日志写入
  12. js控制文本框仅仅能输入中文、英文、数字与指定特殊符号
  13. 【LeetCode】29. Divide Two Integers
  14. Session的两种实现
  15. poj 2369 Permutations (置换入门)
  16. Windows+Apache2.4.10+PHP7.0+MySQL5.6.21安装
  17. 基础二 day4 日记
  18. left join 原理分析
  19. Java NIO学习之Buffer
  20. python全栈开发day86-CRM增删改查 分页

热门文章

  1. 模糊测试(fuzz testing)介绍(一)
  2. Android开发学习之路-让注解帮你简化代码,彻底抛弃findViewById
  3. CPU占用率呈正弦实现,及实时输出进程和线程的CPU占用率
  4. iOS中多线程知识总结(一)
  5. C#实现约瑟夫环问题
  6. Sql Server系列:键和约束
  7. 【WP8.1开发】用手机来控制电脑的多媒体播放
  8. Makefile
  9. The network bridge on device VMnet0 is not running
  10. gsoap设置超时