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