我偶尔会使用一个volatile实例变量,在这种情况下,我有两个线程读取/写入它并且不希望获得锁定的开销(或潜在的死锁风险); 例如,计时器线程定期更新在某些类上作为getter公开的int ID:
public class MyClass {
private volatile int id;
public MyClass() {
ScheduledExecutorService execService = Executors.newScheduledThreadPool(1);
execService.scheduleAtFixedRate(new Runnable() {
public void run() {
++id;
}
}, 0L, 30L, TimeUnit.SECONDS);
}
public int getId() {
return id;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题:鉴于JLS只能保证32位读取将是原子有任何一点曾经使用挥发性长时间?(即64位).
警告:请不要回复说使用volatile结束synchronized是预优化的情况; 我很清楚如何/何时使用,synchronized但有些情况volatile更可取.例如,在定义用于单线程应用程序的Spring bean时,我倾向于使用volatile实例变量,因为无法保证Spring上下文将初始化主线程中的每个bean的属性.
有没有办法volatile在Java中声明数组元素?即
volatile int[] a = new int[10];
Run Code Online (Sandbox Code Playgroud)
声明数组引用 volatile,但数组元素(例如a[1])仍然不是volatile.所以我正在寻找类似的东西
volatile int[] a = new volatile int[10];
Run Code Online (Sandbox Code Playgroud)
但它不会那样工作.有可能吗?
我正在写一个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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以我有几个问题.
1.假设属性是只读的,我必须使用synchronize的 getProperty?
2.是否有意义做this.key_values = Collections.synchronizedMap(tmp_map)的reloadConfig?
谢谢.