0

我想对此发表意见以解决一个小纠纷。任何帮助将不胜感激。

我已经编写了自己的附加到记录器的文件处理程序。这是一个文件处理程序并被多个线程访问,我使用同步以确保在写入过程中没有冲突。此外,它是一个滚动日志,所以我也关闭和打开文件,也不希望出现任何问题。

他对此的回应是(从电子邮件中粘贴)

我坚信处理程序中的同步非常糟糕。对于这样简单的任务来说太复杂了。所以,我会说为什么不为每个线程使用一个实例?

从性能和内存管理的角度来看,您会说什么更好。非常感谢您的任何回复。每当在多线程应用程序中涉及写入和读取时,我一生都在 java 应用程序上使用同步,并且没有听说过任何严重的性能问题。

所以请我想知道是否有任何问题,我真的应该每个线程切换到一个实例。

一般来说,使用同步的缺点是什么?

编辑:我编写自定义文件处理程序(是的,我确实喜欢 slf4j)的原因是因为我的自定义处理程序同时处理两个文件,此外,除了写入文件之外,我还执行了一些其他功能。

4

3 回答 3

5

另一种解决方案是使用一个单独的线程来完成(它自己的成本很高)写入并使用并发队列来传递来自域线程的日志消息

这里的关键部分是推送到队列比写入文件的成本要低得多,这意味着并发日志调用的干扰更少

然后对 log 的调用会像这样记录

private static BlockingQueue logQueue = //...

public static void log(String message){
//construct&filter message
    logQueue.add(message);
}

然后在记录器线程中它看起来像

while(true){
    String message = logQueue.poll();
    logFile.println(message);//or whatever you are doing
}
于 2013-05-28T18:34:43.607 回答
2

同步的缺点是任何时候只有一个线程可以访问该部分代码,这意味着您的代码从多线程中几乎看不到什么好处,即应用程序的同步部分只能与单个线程一样快。(处理同步状态的开销也很小,所以可能会慢一点)

但是,在您不希望线程相互干扰的主题中,例如写入文件,从同步中获得的安全性是最重要的,应该接受性能损失。

于 2013-05-28T18:19:38.643 回答
2

与所有 I/O 一样,除了互斥之外,您别无选择。从理论上讲,您可能会使用累积日志条目的无锁队列建立一个复杂的方案,但它的实用性,尤其是它的可靠性,将是非常值得怀疑的:如果没有仔细设计,您可能会得到一个日志导致的 OOME,让应用程序挂起由于您没有清理的线程等。

请记住,假设您正在使用缓冲 I/O,您已经拥有了一个队列,从而最大限度地减少了占用锁的时间。

于 2013-05-28T18:35:33.647 回答