在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; } } } 所以我有几个问题. 谢谢. 解决方法
>假设在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指出它不会是线程安全的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |