Java getResourceAsStream随机且不经常返回null

Java getResourceAsStream随机且不经常返回null,java,singleton,Java,Singleton,在使用getResourceAsStream时,我很少遇到空指针异常,就像每10000次运行一次一样。这就是这个班的样子 public class ConfigLoader{ private Properties propies; private static ConfigLoader cl = null; private ConfigLoader(){ propies = new Properties; } public static ConfigLoade

在使用getResourceAsStream时,我很少遇到空指针异常,就像每10000次运行一次一样。这就是这个班的样子

public class ConfigLoader{
  private Properties propies;
  private static ConfigLoader cl = null;
  private ConfigLoader(){
        propies = new Properties;
  }
  public static ConfigLoader getInstance(){
    if(cl == null){
          cl = new ConfigLoader();
    }
  }

  public boolean Load(){
   try{
         propies.load(this.getClass().getResourceAsStream("/config.properties"));          
   }
   catch(NullPointerException e){
         System.out.println("File Does Not Exist");
         return false;
   }
   return true;
   }
}
如图所示,该类是作为单例实现的。该资源显然存在,并且大部分时间都被检测到,但我不确定为什么它偶尔会失败,这对我来说真的很奇怪

  • 它将有助于找出什么是null(propies?getResourceAsStream返回的值?)
  • 我的猜测是,您从多个线程调用
    getInstance
    ,其中一个线程得到一个未正确初始化的ConfigLoader,因为您的单线程不是线程安全的
  • 因此,我首先通过日志记录确认,当它失败时,这是因为
    propies
    为null,如果是这样,请确保单例线程安全,例如:

    private static final ConfigLoader cl = new ConfigLoader;
    public static ConfigLoader getInstance() { return cl; }
    
    或者更好地使用枚举:

    public enum ConfigLoader{
      INSTANCE;
      private Properties propies;
      private ConfigLoader(){
        propies = new Properties;
      }
    
      public static ConfigLoader getInstance(){ return INSTANCE; }
    
      public boolean Load(){
       try{
             propies.load(this.getClass().getResourceAsStream("/config.properties"));          
       }
       catch(NullPointerException e){
             System.out.println("File Does Not Exist");
             return false;
       }
       return true;
       }
    }
    

    或者,如果
    getResourceAsStream(“/config.properties”)
    返回null,这可能是由于资源未包含在jar中而导致的打包问题吗?

    Hi,这不是打包问题,因为它99%的时间都在工作。我确信这一点。空值发生得非常快sporadically@BobLoblawgetResourcesAsStream对于给定的jar不应该随机失败,除非你随机搞乱了类加载器……有没有办法测试其中一个线程是否有一个没有正确初始化的类加载器对象?@BobLoblaw(失败的)代码运行在哪个jvm/处理器上?(老实说,不确定类加载器的初始化)@BobLoblaw x86处理器有一个相当强大的内存模型,可以防止发生一些重新排序/缓存问题。PowerPC的内存模型较弱。jvm也发挥了作用(hotspot通常不会在初始化对象字段之前对构造函数引用的发布重新排序)。例如,见: