java.util.logging.Logger:文件扩展名在“;超时“;

java.util.logging.Logger:文件扩展名在“;超时“;,java,java.util.logging,Java,Java.util.logging,我正在使用java.util.logging.Logger并将其包装在一个单例中。所以我可以在我的程序中以一种很好的方式访问它(也可以在线程中) 我认为这比一个全球性的或传递的参考要好得多 我在main中一开始就调用LogTest.init()。 然后,我在需要记录日志的任何地方调用LogTest.get()。即使它是一根线 LogTest.get().info ("blabla"); 这很有效。但我认识到,在1-2分钟后,当我没有将一些行打印到日志文件时,文件扩展名会增加1 test.log

我正在使用java.util.logging.Logger并将其包装在一个单例中。所以我可以在我的程序中以一种很好的方式访问它(也可以在线程中)

我认为这比一个全球性的或传递的参考要好得多

我在main中一开始就调用LogTest.init()。 然后,我在需要记录日志的任何地方调用LogTest.get()。即使它是一根线

LogTest.get().info ("blabla");
这很有效。但我认识到,在1-2分钟后,当我没有将一些行打印到日志文件时,文件扩展名会增加1

test.log->test.log.1 .... test.log.1->test.log.2

我认为只有当文件大小超过最大值(100k的FileHandler)时才会出现这种情况


知道这是与线程或文件处理程序相关的问题吗?为什么会有这种行为?我不希望日志文件发生这种变化。

与您的问题无关,您的代码更像是一个带有静态方法的类,而不是一个单例

发件人:

Singleton是一种有用的设计模式,只允许一个 实例,但常见错误可能会在不经意间允许 要创建多个实例

使用代码,您仍然可以调用
new LogTest()
任意次数,因此允许创建多个
实例


作为单例的代码如下所示:

public class LogTest {

    private static LogTest theInstance;

    private LogTest() {
        LogManager.getLogManager().reset();
    }

    public static synchronized LogTest getInstance() {
        if(theInstance == null) {
            theInstance = new LogTest();
        }
        return theInstance;
    }

    public Logger getLogger() throws Exception {
        Logger l = LogManager.getLogManager().getLogger("test");
        if (l == null) {
            l = Logger.getLogger("test");
            FileHandler fh = new FileHandler("test.log", 100000, 1, true);
            l.addHandler(fh);
            l.setLevel(Level.parse("INFO"));
        }
        return l;
    }
}
当您想使用它时:

LogTest.getInstance().getLogger().log(...);

与您的问题无关,您的代码更像是一个带有静态方法的类,而不是一个单例

发件人:

Singleton是一种有用的设计模式,只允许一个 实例,但常见错误可能会在不经意间允许 要创建多个实例

使用代码,您仍然可以调用
new LogTest()
任意次数,因此允许创建多个
实例


作为单例的代码如下所示:

public class LogTest {

    private static LogTest theInstance;

    private LogTest() {
        LogManager.getLogManager().reset();
    }

    public static synchronized LogTest getInstance() {
        if(theInstance == null) {
            theInstance = new LogTest();
        }
        return theInstance;
    }

    public Logger getLogger() throws Exception {
        Logger l = LogManager.getLogManager().getLogger("test");
        if (l == null) {
            l = Logger.getLogger("test");
            FileHandler fh = new FileHandler("test.log", 100000, 1, true);
            l.addHandler(fh);
            l.setLevel(Level.parse("INFO"));
        }
        return l;
    }
}
当您想使用它时:

LogTest.getInstance().getLogger().log(...);

发生这种情况的原因可能在于:

还需要注意的是,如果没有对记录器的强引用,则与字符串名称关联的记录器可能会在任何时候被垃圾收集。此方法的调用方必须检查返回值是否为null,以便正确处理记录器已被垃圾收集的情况

由于您在一分钟或几分钟内没有访问记录器,并且代码中没有对记录器对象的引用,因此它可能是垃圾收集的,当您稍后调用
getLogger()
时,它可能返回null


如果@Mark有一个合适的单例作为指针,它将不会被垃圾收集。

发生这种情况的原因可能在于:

还需要注意的是,如果没有对记录器的强引用,则与字符串名称关联的记录器可能会在任何时候被垃圾收集。此方法的调用方必须检查返回值是否为null,以便正确处理记录器已被垃圾收集的情况

由于您在一分钟或几分钟内没有访问记录器,并且代码中没有对记录器对象的引用,因此它可能是垃圾收集的,当您稍后调用
getLogger()
时,它可能返回null


如果您有一个合适的单例作为@Mark的指针,它就不会被垃圾收集。

是的,您是对的。当我为我的问题创建了一个简单的示例时,我跳过了私有构造函数,并且忽略了这样一个事实,即它不是singleton,而是anymmore。真正更复杂的单身汉确实有这种能力。但是对于这个问题,这没有任何区别。是的,你是对的。当我为我的问题创建了一个简单的示例时,我跳过了私有构造函数,并且忽略了这样一个事实,即它不是singleton,而是anymmore。真正更复杂的单身汉确实有这种能力。但对于这个问题,它没有任何区别。在我真正的代码中,这个类是一个真正的单例。但问题是记录器的实例不是我的singleton中的成员。我总是向LogManager请求指定的记录器。这样GC肯定会删除它。谢谢你的提示。现在,将记录器作为单例中的一个变量运行良好。在我的实际代码中,该类是一个真正的单例。但问题是记录器的实例不是我的singleton中的成员。我总是向LogManager请求指定的记录器。这样GC肯定会删除它。谢谢你的提示。现在将记录器作为单例中的一个变量,它工作得很好。