通过静态方法访问静态对象/资源会有性能问题吗?

时间:2013-09-19 12:06:23

标签: java multithreading static-methods static-members

我有一个类,它读取一个xml文件并在私有静态数据结构(比如HashMap)中填充它们。这个初始种群发生在一个静态块中。然后我有方法获取给定键的值,实习生引用静态HashMap。在这种情况下,当多个线程试图获得给定键的值时,是否会有任何性能损失;比如,当一个线程正在读取静态对象时,其他线程必须等待。

  public class Parser
  {
       private static HashMap resource = new HashMap();

       static
       {
         parseResource();
       }

       private Parser()
       {
       }

       private static parseResource()
       {
           //parses the resource and populates the resource object
       }

       public static Object getValue( String key)
       {
           //may be some check will be done here, but not any     
           //update/modification actions
          return resource.get(key);
       }    
   }

4 个答案:

答案 0 :(得分:1)

首先,值得注意的是,这与static几乎没有关系。没有“静态对象”这样的东西 - 只有对象,并且有些字段和方法可能是静态的,也可能不是静态的。例如,可能有一个实例字段和一个静态字段,它们都引用同一个对象。

就线程安全而言,您需要考虑您对单个对象感兴趣的操作的安全性 - 多个线程如何“到达”该对象并不重要。

  

就像,当一个线程正在读取静态对象时,其他线程必须等待。

不,它没有。

如果你只是HashMap读取后,以一种阻止其它线程可见的方式构建它,直到它完成为止,那很好。 (重新阅读您的评论后,getValue就会出现这种情况。)

如果您需要在其他线程正在读取地图时执行地图上的任何突变,请考虑使用ConcurrentHashMap或使用同步。

来自docs for HashMap

  

请注意,此实现未同步。如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步。

答案 1 :(得分:0)

您的示例代码中没有发生锁定,因此多线程无法等待。

答案 2 :(得分:0)

刚刚添加到Jon Skeet的答案中,对于这种用法,您可能需要考虑Guava的ImmutableMap,它强制实现不变性。

答案 3 :(得分:-1)

只需使用synchronized关键字,一切都应该正常。