【问题标题】:Will accesing static object/resources through static methods have performance issue?通过静态方法访问静态对象/资源会有性能问题吗?
【发布时间】:2013-09-19 12:06:23
【问题描述】:

我有一个类可以读取 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);
       }    
   }

【问题讨论】:

  • 只要读取过程没有定义为同步,线程就不会等待其他线程完成。

标签: java multithreading static-methods static-members


【解决方案1】:

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

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

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

不,它没有。

如果您只是在构建HashMap 之后读取它,以防止它在完成之前对其他线程可见,那很好。 (重读了您的评论,getValue 似乎就是这种情况。)

如果您需要在其他线程读取映射时对映射执行任何更改,请考虑使用ConcurrentHashMap 或使用同步。

来自docs for HashMap

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

【讨论】:

  • 为了完整起见,我建议您查找实现单例的良好实践。在 Java 6 及之后,您可以使用 Enum(推荐的编写 Singletons 的方式)来正确封装初始化的只读数据。
【解决方案2】:

您的示例代码中没有发生锁定,因此不可能有多个线程需要等待。

【讨论】:

    【解决方案3】:

    只是添加到 Jon Skeet 的答案中,对于这种用途,您可能需要考虑 Guava 的 ImmutableMap,它强制执行不变性。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • HashMap 可以安全地从多个线程读取,因此无需同步。
      猜你喜欢
      • 2012-03-30
      • 2012-10-07
      • 1970-01-01
      • 2011-12-29
      • 2012-11-05
      • 2011-04-17
      • 1970-01-01
      • 2015-12-29
      • 2014-04-25
      相关资源
      最近更新 更多