我有一个多线程Java 7程序(一个jar文件),它使用JDBC执行工作(它使用一个固定的线程池)。
程序工作正常,当它从多个并发线程进展到命令shell控制台窗口(System.out.printf())时,它会记录事情。
除了控制台输出之外,我还需要为这个程序添加从多个线程写入单个纯ASCII文本日志文件的能力。
输出量较小,文件相对较小,因为它是日志文件,而不是数据文件。
你能建议一个好的和相对简单的设计/方法来完成这个使用Java 7的功能(我还没有Java 8)?
任何代码示例也将受到赞赏。
thank you very much
编辑:我忘了补充:根据官方Java文档,在Java 7中使用Files.newOutputStream()静态工厂方法被认为是线程安全的。这是从多个线程中编写单个共享文本日志文件的最简单的选项吗?
如果你想记录输出,为什么不使用日志库,比如log4j2?这将允许您根据您的特定需求定制日志,并且可以在不同步标准输出线程的情况下进行日志记录(您知道运行System.out.print涉及锁定System.out吗?)
编辑:对于后者,如果您记录的东西是线程安全的,并且您可以将LMAX' disruptor.jar添加到您的构建中,您可以配置异步日志记录器(只需添加"async"),它将有一个日志线程负责整个消息格式化和写入(并保持日志消息的顺序),同时允许您的线程顺利运行。
考虑到您已经说过输出量很低,最简单的选择可能是编写一个线程安全的写入器,它使用同步来确保一次只有一个线程可以实际上写入文件。
如果你不希望线程互相阻塞,你可以有一个专门用于写的线程,使用BlockingQueue
-线程添加写作业(以任何他们需要的形式-可能只是字符串)到队列中,并且单个线程从队列中取出值并将它们写入文件。
无论哪种方式,抽象出专门用于此目的的类背后的细节都是值得的(理想情况下,出于可测试性和灵活性的原因实现接口)。这样,您就可以稍后更改实际的底层实现——例如,从同步方法开始,如果需要,稍后再移动到生产者/消费者队列。
保留一个通用的PrintStream
引用,您将写入(而不是System.out
)并将其设置为System.out
或将其通道通过FileOutputStream
取决于您想要的。
你的代码不会改变太多(几乎没有),PrintStream
已经同步了。