Java并发编程(六) 一个日志服务的例子
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java并发编程(六) 一个日志服务的例子,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1941字,纯文字阅读大概需要3分钟。
内容图文
日志服务需要提供的功能有:
可以从外部安全地开启和关闭日志服务;
可以供多个线程安全地记录日志消息;
在日志服务关闭后,可以把剩余未记录的消息写入日志文件;
public class LogService { private final BlockingQueue<String> msgQueue; //阻塞的消息队列保存日志消息 privatefinal PrintWrite writer; //写消息到日志文件 privatefinal LoggerThread logThread; //写日志的线程 privateboolean isShutdown; //表示日志服务是否已经关闭 public LogService(String file) throws FileNotFoundException { logThread = new LogThread();
writer = new PrintWrite(file); } publicvoid start() { logThread.start(); //启动日志线程 Runtime.getRuntime().addShutdownHook(new Thread() { //添加关闭钩子,确保在没有调用stop方法的情况下,日志文件最终仍然会关闭 stop(); }); } publicvoid stop() { synchronized(this) //需要先加锁,再修改isShutdown的值 { if(!isShutdown) { isShutdown = true; logThread.interrupt(); //中断日志线程 } } } publicvoid log(String message) { synchronized(this) //需要先加锁,再访问isShutdown的值 { if(!isShutdown) //若日志服务没有关闭,则将消息加入消息队列,这里是典型的先验条件,声明isShutdown为volatile并不能解决同步的问题 msgQueue.put(message); elsethrownew IllegalStateException("Log Service is shutdown"); //若日志服务已经关闭,则抛出IllegalStateException } } privateclass LoggerThread extends Thread { publicvoid run() { try { while(true) { try { synchronized(LogService.this) { if(isShutdown && msgQueue.size() == 0) //如果服务已经关闭并且消息队列中已经没有剩余的消息,则关闭日志线程 break; writer.write(msgQueue.take()); } } catch(InterruptedException ex){} //忽略中断消息 } } finally { writer.close(); //关闭日志文件 } } } }
在上面的例子中,有以下几个地方值得注意:
日志服务不应该在收到关闭消息时立即停止,而应该将消息队列中剩余的消息写入到日志文件之后再关闭。如果决定丢弃这些消息,那么应该先清空消息队列,否则调用log方法的线程会一直阻塞;
上例中使用isShutdown来标识服务是否已经关闭,调用log方法的线程首先检测isShutdown的值,这样多个线程就需要对isShutdown互斥访问,而不能简单使用volatile修饰isShutdown;
在日志线程中,检测到中断消息后,直接忽略了,最后在finally中也没有再恢复中断状态,这是因为我们知道线程的所有者日志服务已经停止了,不再需要恢复中断;
上例中使用了关闭钩子,在start方法中添加了关闭钩子线程,可以确保即使调用者没有调用stop方法停止日志服务,日志服务最终在JVM停止之前也会关闭;
下面简单介绍一下关闭钩子:
关闭钩子是通过Runtime.addShutdown方法注册的但并不立刻启动任务的线程,JVM在关闭过程中,首先会启动执行已经注册的关闭钩子线程。关闭钩子通常用于实现服务或者应用程序的清理工作,并且不宜在其中执行耗时的任务,会延迟JVM关闭的时间。
参考资料 《Java并发编程实战》
原文:http://www.cnblogs.com/jqctop1/p/4952422.html
内容总结
以上是互联网集市为您收集整理的Java并发编程(六) 一个日志服务的例子全部内容,希望文章能够帮你解决Java并发编程(六) 一个日志服务的例子所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。