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

如何在JAVA多线程环境中从config.properties加载属性,java,multithreading,properties,multiprocessing,Java,Multithreading,Properties,Multiprocessing,我有一个从config.properties文件加载主类属性的程序,如下所示: public class DirectoryWatcher { public static String FOLDER = null; Properties prop = new Properties(); prop.load(new FileInputStream(new File(configPath))); FOLDER = prop.getPr

我有一个从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");
    }        
许多线程需要这个文件夹,因为我将它设置为公共静态,所以线程可以使用它

我不喜欢这种编程,我正在寻找一些最佳实践实现。 你能给我推荐更好的吗?
谢谢。

对我来说,这就足够了

public class DirecoryWatcher{
    private static String FOLDER;

    public static synchronized getFolder(){
        if(FOLDER == null){
            // FOLDER = your loading code
        }
        return 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;
    }
}
此代码将为您提供线程安全性,并支持任何给定数量的属性。它还增强了代码的封装,您可以添加一些逻辑,而不仅仅是公开文件的内容

此外,在这种情况下,属性直到第一次需要时才会加载。如果从未使用过属性,则不会读取该属性。这样可以提高内存使用率,不会将内存浪费在不需要的值上


另一个重要的事情是,通过这个实现,您的属性Looper-C类可以非常容易地处理错误和异常。使用另一种方法,您将处理问题的责任委托给请求属性的对象。

对我来说,这就足够了

public class DirecoryWatcher{
    private static String FOLDER;

    public static synchronized getFolder(){
        if(FOLDER == null){
            // FOLDER = your loading code
        }
        return 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;
    }
}
此代码将为您提供线程安全性,并支持任何给定数量的属性。它还增强了代码的封装,您可以添加一些逻辑,而不仅仅是公开文件的内容

此外,在这种情况下,属性直到第一次需要时才会加载。如果从未使用过属性,则不会读取该属性。这样可以提高内存使用率,不会将内存浪费在不需要的值上

另一个重要的事情是,通过这个实现,您的属性Looper-C类可以非常容易地处理错误和异常。使用另一种方法,您可以将处理问题的责任委托给请求属性的对象。

您可以将其设置为最终:

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");
}
这将确保从任何线程都可以看到它。如果您有多个属性,还可以使用使用枚举且线程安全的属性。

您可以将其设置为最终属性:

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");
}
这将确保从任何线程都可以看到它。如果您有多个属性,还可以使用使用枚举且线程安全的属性。

您是否可以使用它来解决此问题

如果有大量信息要加载,也可以使用延迟加载来加载文件夹。

也许您可以使用延迟加载来解决此问题


如果要加载大量信息,也可以对文件夹使用延迟加载。

您可以像这样定义一个简单的属性文件读取器

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);
            }
        }
    }       
}   
}
DirectoryWatcher.directoryWatcher.getProperty(DirectoryProperties.FOLDER.getCode());
特定的属性文件可以如下读取

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

可以定义为枚举类型的属性。。。你可以在这里列出你的财产

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

您可以在任何线程中使用您的属性。像这样

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);
            }
        }
    }       
}   
}
DirectoryWatcher.directoryWatcher.getProperty(DirectoryProperties.FOLDER.getCode());

您可以在需要时使用说明。

您可以像这样定义一个简单的属性文件读取器

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);
            }
        }
    }       
}   
}
DirectoryWatcher.directoryWatcher.getProperty(DirectoryProperties.FOLDER.getCode());
特定的属性文件可以如下读取

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

可以定义为枚举类型的属性。。。你可以在这里列出你的财产

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

您可以在任何线程中使用您的属性。像这样

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);
            }
        }
    }       
}   
}
DirectoryWatcher.directoryWatcher.getProperty(DirectoryProperties.FOLDER.getCode());

您可以根据需要使用说明。

最佳做法是使用Java命名约定。您不喜欢文件夹大写?我希望它是最终的。好的,很好,谢谢!其他线程的可接受性如何?主题外。如何从DirectoryWatcher方法中调用prop方法?最佳实践是使用Java命名约定。您不喜欢文件夹大写?我希望它是最终的。好的,很好,谢谢!其他线程的可接受性如何?主题外。如何从DirectoryWatcher方法中调用prop方法?如果配置中有许多属性,而所有线程都需要这些属性?好的,我将添加支持任意数量属性的实现。@prilla,想象一下,如果您应该一个接一个地加载属性,并且如果您在配置中有许多属性,而您在所有线程中都需要这些属性,那么代码的长度是多少?好的,我将添加支持任意数量属性的实现。@prilla,im 如果要逐个加载属性,请调整代码长度。。。