记录时使用同步 [英] Using Synchronization while Logging

查看:78
本文介绍了记录时使用同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我使用Java.Util.Logging编写了自己的Logging实用程序

In my application I have written my own Logging utility using Java.Util.Logging

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.SimpleFormatter;



public class Logger {

    public final static String PROPERTIES_FILE = "Logger.properties";
    private static java.util.logging.Logger logger = null;

    private static void initialize() {
        try {
            logger = java.util.logging.Logger.getLogger(Logger.class.getName());
            FileHandler fh = new FileHandler("D:\\MyLogFile.log", true);
            logger.addHandler(fh);
            logger.setLevel(Level.ALL);
            SimpleFormatter formatter = new SimpleFormatter();
            fh.setFormatter(formatter);
            logger.log(Level.INFO, "Test Message Logged");

        }
        catch (IOException e) {
          System.out.println("Warning: Unable to read properties file " +
                             PROPERTIES_FILE );
        }   
      }

    public static synchronized java.util.logging.Logger getLogger(String name)
    {
        if(logger==null)
        {
        Logger.initialize();
        }
        logger.getLogger(name);
        return logger;
    }


}

我需要对getLogger方法使用同步吗?请发表您的意见. (此代码在多线程环境中运行)

Do I need to use Synchronization for getLogger method? Please give your comments. (This code is running in Multi-threaded environment)

推荐答案

我同意其他评论者的观点,在这里似乎不需要惰性初始化.初始化logger变量的最简单方法是在静态初始化器中,该初始化器保证在类加载时仅执行一次:

I agree with other commenters that lazy initialization doesn't seem necessary here. The simplest way to initialize the logger variable is in a static initializer, which is guaranteed to only execute once at class loading time:

public class Logger {

    public final static String PROPERTIES_FILE = "Logger.properties";
    private static java.util.logging.Logger logger = null;

    private static void initialize() {
        try {
            logger = java.util.logging.Logger.getLogger(Logger.class.getName());
            FileHandler fh = new FileHandler("D:\\MyLogFile.log", true);
            logger.addHandler(fh);
            logger.setLevel(Level.ALL);
            SimpleFormatter formatter = new SimpleFormatter();
            fh.setFormatter(formatter);
            logger.log(Level.INFO, "Test Message Logged");

        }
        catch (IOException e) {
          System.out.println("Warning: Unable to read properties file " +
                             PROPERTIES_FILE );
        }   
    }

    static {
        initialize();
    }

    public static java.util.logging.Logger getLogger(String name)
    {
        logger.getLogger(name);
        return logger;
    }


}

但是,您可以避免与双重检查锁定的大多数同步.

However, You can avoid most synchronization with double-checked locking.

public class Logger {

    // note: volatile is required
    private volatile static java.util.logging.Logger logger = null;

    //... 

    public static java.util.logging.Logger getLogger(String name)
    {
        if(logger==null)
        {
           synchronized(Logger.class) 
           {
              if(logger == null)
                Logger.initialize();
              }
           }
        }
        logger.getLogger(name);
        return logger;
    }
}

实际上,在您的情况下,如果您重写初始化函数,以便在将记录器完全分配给局部变量之前将其配置为本地变量,则可以完全避免同步:

In fact, in your case I think you can avoid synchronization altogether if you rewrite your initialize function so that it completely configures the logger in an local variable prior to assigning it to the (volatile) class variable:

private volatile static java.util.logging.Logger logger = null;
private static void initialize() {
    try {
        Logger logger = java.util.logging.Logger.getLogger(Logger.class.getName());
        FileHandler fh = new FileHandler("D:\\MyLogFile.log", true);
        logger.addHandler(fh);
        logger.setLevel(Level.ALL);
        SimpleFormatter formatter = new SimpleFormatter();
        fh.setFormatter(formatter);
        logger.log(Level.INFO, "Test Message Logged");

        Logger.logger = logger;
    }
    catch (IOException e) {
      System.out.println("Warning: Unable to read properties file " +
                         PROPERTIES_FILE );
    }   

    public static java.util.logging.Logger getLogger(String name)
    {
        if(logger==null)
        {
        Logger.initialize();
        }
        logger.getLogger(name);
        return logger;
    }
}

这有可能使initialize()执行多次,但是我认为您并不在乎,只要每次getLogger调用都会有一个有效的记录器实例,即使该实例有所不同.

This has a potential to have initialize() execute several times, but I don't think you care, so long that every getLogger invocation will have a valid logger instance, even if that instance varies.

这篇关于记录时使用同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆