Java同步性能



我想就这件事征求一下意见,以解决一个小争端。如有任何帮助,我将不胜感激。

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

他的回复是(粘贴自电子邮件)

我坚信Handler中的同步非常糟糕。它对这么简单的任务来说太复杂了。所以,我想说为什么不使用一个呢每个线程实例数?

从性能和内存管理的角度来看,你认为哪个更好?非常感谢您的回复。每当在多线程应用程序中涉及写和读时,我一直在java应用程序中使用同步,并且没有听说过任何严重的性能问题。

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

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

编辑:我编写自定义文件处理程序的原因(是的,我确实喜欢slf4j),是因为我的自定义处理程序一次处理两个文件,此外,我还有一些其他函数在写入文件之上执行。

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

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

对日志的调用将记录为

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

那么在logger线程中,它将看起来像

while(true){
    String message = logQueue.poll();
    logFile.println(message);//or whatever you are doing
}

对于所有I/O,除了互斥之外几乎没有选择。理论上,您可以构建一个具有无锁队列的复杂方案,该队列可以积累日志条目,但是它的实用性,特别是它的可靠性将非常值得怀疑:如果不仔细设计,您可能会获得由日志引起的OOME,使应用程序由于未清理的线程而挂起,等等。

请记住,假设您使用的是缓冲I/O,那么您已经有了一个相当于队列的东西,可以最大限度地减少占用锁的时间。

同步的缺点是在任何时候只有一个线程可以访问代码的那部分,这意味着你的代码将看不到多线程的好处,也就是说,你的应用程序的同步部分将只和单个线程一样快。(处理同步状态的开销也很小,所以可能会慢一点)

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

相关内容

  • 没有找到相关文章

最新更新