【发布时间】:2018-09-08 12:34:45
【问题描述】:
如果我这样修改the stock initialization-on-demand holder idiom example:
public class Something {
//internal params, unchangeable after the initialization
private final List<String> params;
//changeable params that will be used for initialization
private final static List<String> initParams = new ArrayList<>();
private Something(List<String> params) {
this.params = params;
}
//allow params to be added prior to initialization
public static void addParam(String param) {
initParams.add(param);
}
private static class LazyHolder {
static final Something INSTANCE =
new Something(Collections.unmodifiableList(initParams));
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
public int calculate() {
return params.size(); //use the internal params somehow
}
}
并按如下方式使用:
- 只有1个线程多次调用
addParam准备初始化(唯一的写线程) - 许多线程(可能在写入线程之前创建)后来调用
getInstance来获取单例实例(许多读取线程) - 对
getInstance的初始调用可以由writing 线程或reading 线程之一执行
这种用法是否安全(尽管很复杂)?
是否会根据哪个线程(读取器或写入器)首先调用 getInstance 而发生变化?
如果静态的initParams 变量是volatile?
如果第一次调用是由reading线程(在writing线程之前创建的)执行的,它的initParams内部视图是否会过时并导致初始化实例也会过时?
【问题讨论】:
标签: java multithreading concurrency thread-safety singleton