Java并发从多个线程写入单个文本文件?

时间:2015-06-03 06:16:29

标签: java multithreading file java-7

我有一个多线程Java 7程序(一个jar文件),它使用JDBC来执行工作(它使用固定的线程池)。

该程序运行正常,它会从多个并发线程进入命令shell控制台窗口(System.out.printf())时记录事物。

除了控制台输出之外,我还需要为这个程序添加写入单个纯ASCII文本日志文件的能力 - 来自多个线程。

输出量很低,文件作为日志文件而不是数据文件会相对较小。

你能否建议一个好的,相对简单的设计/方法来使用Java 7功能完成这项工作(我还没有Java 8)?

任何代码示例也将受到赞赏。

非常感谢

编辑:

我忘了添加:在Java 7中使用Files.newOutputStream()声明静态工厂方法是线程安全的 - 根据官方Java文档。这是从多个线程编写单个共享文本日志文件的最简单选项吗?

3 个答案:

答案 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%","")也已同步。