【问题标题】:Java synchronization performanceJava同步性能
【发布时间】:2013-05-28 18:09:30
【问题描述】:

我想就此提出意见以解决一个小纠纷。任何帮助将不胜感激。

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

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

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

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

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

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

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

【问题讨论】:

  • 理论讨论很好(理论上(原文如此))。但是要定量地回答这个问题,您必须测试 性能(您可以使用caliper 来解决这个问题)。同步确实具有性能影响 - 这有多严重取决于线程之间对受保护资源的争用。我不明白“每个线程一个实例”,这是否意味着每个处理程序有一个单独的文件?
  • 当 log4j、slf4j 和 apache commons logging 都存在时,你为什么要这样做?记录没有解决吗?你为什么要浪费你的时间试图改进已经做了很多次的事情?
  • 我怀疑任何应用程序都会在日志记录上花费大量运行时间——因此性能可能不值得考虑,而不仅仅是拥有一个可靠的解决方案。我非常怀疑这是一个瓶颈。
  • @earcam 我猜他的意思是为每个线程创建一个处理程序,这样他们就不会干扰。他的解释还在来,但我也不是引用理解它。
  • @Pescis 日志实际上经常是现实生活中的性能威胁,但它也可以通过日志级别过滤器进行系统控制。

标签: java multithreading synchronization locking readwritelock


【解决方案1】:

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

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

对 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
}

【讨论】:

  • +1 = 迄今为止最好的回复。将日志请求对象指针推送到队列上的锁定轮比与每个需要记录日志的线程试图获得一些互斥锁相比要好得多。 LogRequestClass + BlockingQueue+logger 线程是一个很好的解决方案。
【解决方案2】:

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

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

【讨论】:

  • 为什么是“无锁”?正如@ratchetfreak 所建议的那样,将日志条目对象排队到生产者-消费者队列中应该没有可靠性问题,并且挂起一个日志写入线程。
  • 这不是“精心设计”——它相当微不足道。
  • @martin 与缓冲 IO 相比有什么好处?
  • @Martin 与单个同步关键字相比,几乎没有任何事情可以证明是“微不足道的”。
【解决方案3】:

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

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

【讨论】:

  • 可以避免实际磁盘写入的同步 - 请参阅@ratchetfreak。
猜你喜欢
  • 2010-10-26
  • 1970-01-01
  • 2018-10-28
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多