【问题标题】:How to use java.util.logging.Logger from different threads?如何使用来自不同线程的 java.util.logging.Logger?
【发布时间】:2015-08-21 23:42:13
【问题描述】:

我正在开发一个带有JTextArea 的简单swing 应用程序来显示来自整个应用程序的日志消息。为了开发这个应用程序,我使用了 MVC 模式的简化版本,其中控制器在两个方向上都介于视图和模型之间:

  • 当用户与摇摆控件交互时,如果此交互需要访问模型(即,它需要读取和/或写入模型),那么摇摆控件引发的事件将调用适当的控制器方法;
  • 当应该更新视图时,控制器会调用视图的一个或多个方法。

几乎所有的异常都在控制器中被捕获并发送到java.util.logging.Logger,如下面的代码sn-p。

public void onWriteFile() {
    try {
        // ...
    }
    catch(IOException ex) {
        Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, "onWriteFile()", ex);
    }

    view.refresh(...);
}

只有以下异常会在自定义图形组件中被捕获并发送到记录器(我从 清单 6 中的示例中获得灵感。Java theory and practice: Be a good (event) listener 的稳健侦听器调用)。

private synchronized void processDrawingEvent(DrawingEvent e) {
    if (e == null) {
        return;
    }

    for (Iterator<DrawingListener> i = listeners.iterator(); i.hasNext();) {
        DrawingListener listener = i.next();
        try {
            switch (e.getStatus()) {
                case DRAWING:
                    listener.drawing(e);
                    break;
                case DONE:
                    listener.done(e);
                    break;
                case DELETED:
                    listener.deleted(e);
                    break;
                }
        } catch (RuntimeException ex) {
            i.remove();
            Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

目前对Logger.log(...) 方法的所有调用都来自同一个线程。但是,如果这个方法被不同的线程调用,我应该使用this这样的解决方案吗?

【问题讨论】:

  • 看看 Log4j2。它有一个内置的异步记录器
  • Logger reference (JDK 7) 明确指出All methods on Logger are multi-thread safe。 ++ 你似乎在调查an specific AsyncFileHandler implementation。我不知道这是否是一个适当的问题。 ++ 对于 IO 密集型日志记录(可能独立于多线程),该答案似乎已经足够了。 ++ 我会说去吧(我不会为你测试它)。
  • 您的开发看起来像一个富客户端(Swing)。我不希望有大量的日志记录。我会保持简单并专注于实际问题。

标签: java multithreading swing logging model-view-controller


【解决方案1】:

这取决于你在这里试图解决什么问题。

从代码正确性的角度来看,您不需要做任何特别的事情来跨多个线程共享同一个Logger 对象。该类是线程安全的。

您链接到的问答正在解决不同的问题;即如何通过将日志记录与写入日志文件分离来防止日志记录 I/O 成为性能瓶颈。

如果您正在试图避免日志记录瓶颈,那么考虑这种方法是值得的。但是,在您的情况下,日志消息的异步处理还有其他问题:

  • 由于您正在将日志消息写入屏幕,如果您将其设为异步,则用户看到的日志消息可能会滞后于实际发生的情况。实际上,如果有很多日志事件,则延迟可能会相当大。 IMO,这是不可取的。

  • 如果日志事件率太高,那么异步处理最终会“备份”并且日志记录成为瓶颈。

  • 写入屏幕比写入文件要昂贵得多。它涉及更多的 CPU 和 I/O,包括 Java 和窗口管理器以及(最终)Java 与之交互以将像素显示到屏幕上的 I/O 设备。 (例如,滚动...)这意味着如果您登录到屏幕而不是文件,则可以维持低得多的记录率。

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 2015-10-13
    • 2019-07-14
    相关资源
    最近更新 更多