简体   繁体   English

如何在JAVA中的多线程环境中从config.properties加载属性

[英]How to load properties from config.properties in multithreaded environment in JAVA


I have program that loads in main class properties from file config.properties like this : 我有程序从文件config.properties加载主类属性,如下所示:

    public class DirectoryWatcher {
       public static String FOLDER = null;
       Properties prop = new Properties();

       prop.load(new FileInputStream(new File(configPath)));
       FOLDER = prop.getProperty("FOLDER");
    }        

Many threads needs FOLDER, because of it I set it to be public static , so threads can use it. 许多线程需要FOLDER,因为我将它设置为公共静态 ,因此线程可以使用它。

I am not like this kind of programming and I am looking for some best practice implementation. 我不喜欢这种编程,我正在寻找一些最佳实践实现。
Can you suggest me something better? 你能给我一些更好的建议吗? Thank you. 谢谢。

For me this would be simply enough 对我来说,这就足够了

public class DirecoryWatcher{
    private static String FOLDER;

    public static synchronized getFolder(){
        if(FOLDER == null){
            // FOLDER = your loading code
        }
        return FOLDER;
    }
}

Make sure to assign the value you read from the file to your static field, so you make sure you read it only once. 确保将从文件中读取的值分配给静态字段,因此请确保只读取一次。

Also, synchronized methods is a good practice for accessing resources, it's not completely mandatory for this case, since you're only reading the file. 此外,同步方法是访问资源的一种很好的做法,对于这种情况,它并不是完全必需的,因为您只是在阅读文件。

You can also make this approach extensible to read any property given as argument. 您还可以使此方法可扩展,以读取作为参数给出的任何属性。 I hardcoded FOLDER for the sake of clarity. 为了清晰起见,我硬编码了FOLDER。

public class DirectoryWatcher{

   private static Map<String,String> properties = new HashMap<String,String>();

   public static synchronized getValueFor(String prop){
       String result = null;
       if( !properties.keySet().contains(prop)){
          result = // your loading code
          properties.put(prop, result);
       }else{
          result = properties.get(prop);
       }
       return result;
    }
}

This code will give you thread-safety and support for any given number of properties. 此代码将为您提供线程安全性并支持任何给定数量的属性。 It also enhance the encapsulation of your code, you can add some logic to it (you're not just exposing the content of your file). 它还增强了代码的封装,你可以为它添加一些逻辑(你不只是暴露文件的内容)。

Besides, following this case, properties are not loaded until they are first required. 此外,在这种情况下,在首次需要属性之前不会加载属性。 If a property is never used, then it won't be read. 如果从未使用过属性,则不会读取它。 That improves your memory usage, you don't waste memory on values you won't need. 这可以提高内存使用率,不会浪费内存在您不需要的值上。

Another important thing to consider is that, with this implementation, your properties loader class can handle errors and exceptions very easily. 另一个需要考虑的重要事项是,通过此实现,您的属性加载器类可以非常轻松地处理错误和异常。 With the other approach, you delegate the responsibility of handling problems to the object that requested the property. 使用另一种方法,您将处理问题的责任委托给请求该属性的对象。

You can make it final: 你可以做到最终:

private static final Properties prop = new Properties();
public static final String FOLDER;

static {
    try {
        prop.load(new FileInputStream(new File(configPath)));
    } catch (IOException ex) {
        //outch => log and exit?
    }
    FOLDER = prop.getProperty("FOLDER");
}

This will ensure that it is visible from any threads. 这将确保从任何线程都可以看到它。 If you have more than a handful of properties, you can also use this example which uses an enum and is thread safe. 如果您拥有多个属性,则还可以使用此示例使用枚举并且是线程安全的。

Maybe you can use Singleton pattern for this problem? 也许你可以使用Singleton模式来解决这个问题?

Also you use lazy loading for folder if you have big number of information for loading. 如果您有大量要加载的信息,也可以对文件夹使用延迟加载。

you can define a simple property file reader like this 你可以像这样定义一个简单的属性文件阅读器

public class LoadDataFromPropertiesFile {

public final static Properties loadPropertiesFile(String fileName) {
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    InputStream inStream=null;

    try {
        inStream =  loader.getResourceAsStream(fileName);
        if (inStream == null) {
            throw new RuntimeException("Couldn't find " + fileName + "in class path");
        }
        Properties prop = new Properties();
        prop.load(inStream);

        return prop;
    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }finally {
        if (inStream != null) {
            try {
                inStream.close();
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }       
}   
}

specific property files can be read like below. 特定属性文件可以如下所示。

public class DirectoryWatcher {
public static final Properties directoryWatcher;
static {
    directoryWatcher =     LoadDataFromPropertiesFile.loadPropertiesFile("config.properties");
}     

} }

Properties you can define as ENUM type ... you can list your properties here 您可以定义为ENUM类型的属性...您可以在此处列出您的属性

public enum DirectoryProperties {
        FOLDER("FOLDER","Directory Type Folder"),
        IMAGE("IMG","Image File");
;

DirectoryProperties(String code, String description) {
    this.code = code;
    this.description = description;

}

public String getCode() {
    return code;
}

public String getDescription() {
    return description;
}

private String code;
private String description;

} }

You can use your properties in any thread. 您可以在任何线程中使用您的属性。 like this 像这样

DirectoryWatcher.directoryWatcher.getProperty(DirectoryProperties.FOLDER.getCode());

you can use description where required. 您可以根据需要使用说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM