加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

在Java中同步访问只读映射的正确方法

发布时间:2020-12-15 08:45:06 所属栏目:Java 来源:网络整理
导读:我正在写一个 DatabaseConfiguration类的模拟,它从数据库读取配置,我需要一些关于同步的建议. 例如, public class MyDBConfiguration{ private Connection cn; private String table_name; private MapString,String key_values = new HashMapString,String(
我正在写一个 DatabaseConfiguration类的模拟,它从数据库读取配置,我需要一些关于同步的建议.
例如,

public class MyDBConfiguration{
   private Connection cn;
   private String table_name;
   private Map<String,String> key_values = new HashMap<String,String>();
   public MyDBConfiguration (Connection cn,String table_name) {
      this.cn = cn;
      this.table_name = table_name;
      reloadConfig();
   }
   public String getProperty(String key){
       return this.key_values.get(key);
   }
   public void reloadConfig() {
      Map<String,String> tmp_map = new HashMap<String,String> ();
      // read  data from database
      synchronized(this.key_values)
      {
          this.key_values = tmp_map;
      }
   }
}

所以我有几个问题.
1.假设属性是只读的,我是否在getProperty中使用同步?
2.在reloadConfig中执行此操作是否有意义.key_values = Collections.synchronizedMap(tmp_map)?

谢谢.

解决方法

>假设在reloadConfig之后不会放入key_values,您将需要同步访问映射的读取和写入.您只是通过同步分配来违反此规定.您可以通过删除synchronized块并将key_values指定为volatile来解决此问题.
>由于HashMap只是有效读取,我不会分配Collections.synchronizedMap而不是Collections.unmodifiableMap(这不会影响Map本身,只是禁止其他人使用此类进行意外放置).

注意:此外,您永远不应同步将要更改的字段.结果非常难以预测.

编辑:关于其他答案.强烈建议所有共享的可变数据必须同步,因为效果是非确定性的. key_values字段是共享的可变字段,必须同步它的赋值.

编辑:并清除与Bruno Reis的任何混淆.如果你仍然填充tmp_map,并且在完成填充之后,volatilefield将是合法的,将它分配给this.key_values,它看起来像:

private volatile Map<String,String>();

  ..rest of class 

   public void reloadConfig() {
      Map<String,String> ();
      // read  data from database

      this.key_values = tmp_map;
   }

你仍然需要相同的风格,否则Bruno Reis指出它不会是线程安全的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读