2012-10-12 59 views
1

我有一个Java应用程序。我正在使用日志formater对象。所有的日志消息应该有这个对象。例如java多线程和静态方法

log.debug(new LogFormatter(x,y,z)) 

但我必须创建新的LogFormatter对象,每个我想记录。如果我用静态方法为例

log.debug(LogFormatter.format(x,y,z)) 

比我没有创建新的对象。但是在一个多线程应用程序中它会正常工作。

如果两个线程使用diff值调用,那么日志记录会变得混乱。

或者是线程局部去

+0

这取决于格式方法中的代码。你可以发布方法实现吗? – Peter

+0

我认为日志会打印出'timestamp,thread-id/name',我认为你不会遇到'LogFormatter.format(..)' –

回答

1

我会使用

private final LogFormatter logFormatter; // immutable object. 

log.debug(logFormatter.format(x,y,z)) 

作为格式化器是不可变的,可以共享。

+0

不适用于静态方法 – Aubin

+0

给出的第一个示例表明该方法不必是静态的。我建议避免这种事情的静态方法,如果你可以,你可能想要能够改变格式化。 –

+0

但是,如果LogFormatter.format(...)方法是无状态的(它不使用任何LogFormatter实例全局字段)并不足以确保线程安全(无论它是否为静态或不是(显然它会如果是非静态的,那么必须是final的,这样才不会在扩展LogFormatter的类中创建有状态的覆盖))? –

1

这将取决于执行记录的最佳方式。如果您将使用本机Java类,那么您应该使用处理日志插入的方法或代码部分的关键字synchronize来处理锁定。

IMO我会建议使用一个日志库,像Log4J的是线程安全的:

注意,像JBoss和GlassFish一些Java应用服务器使用Log4j来处理记录工作。

+0

问题'使用同步日志不适用于高度并发的应用程序:这是一个瓶颈。 – Aubin

+0

@Aubin'synchronized'与编写日志条目的代价相比是微不足道的。我建议你不要以这种方式写这么多的日志,以至于不管用。 –

+0

当您将注销切换至高于所有瓶颈时,具有登录功能的多线程高度并发应用程序的行为完全不同。 – Aubin

0

这取决于两件事情:

  1. 无论LogFormatter.format(x,y,z)方法是线程安全的。
  2. 您的记录器实现是否线程安全。

如果这两个条件都成立,那么您可以在多线程环境中使用您的方案,并且不会出现错误。

具体来说,您的记录器实现应该是线程安全的,因为它将对基础输出机制的访问进行同步:例如,通过确保一次只打印一个日志记录。

0

为了避免只有在记录打开时线程之间的同步,我被用来关联每个线程的一个日志链。 难点在于将几个文件加入 - 离线 - 了解正在发生的事情。 每行日志都有一个日期和一个线程ID。