package test1;
import java.util.Random;
public class OneInstanceService {
// use volatile or final,them has same effect,
// but difference volatile or final in DCL demo?
public int i_am_has_state;
private static OneInstanceService test;
private OneInstanceService() {
i_am_has_state = new Random().nextInt(200) + 1;
}
public static OneInstanceService getTest1() {
if (test == null) {
synchronized (OneInstanceService.class) {
if (test == null) {
test = new OneInstanceService();
}
}
}
return test;
}
public static void reset() {
test = null;
}
}
//----------------------------------------
package test1;
import java.util.concurrent.CountDownLatch;
public class Test1 {
public static void main(String[] args) throws InterruptedException {
for (;;) {
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
Thread t1 = new Thread() {
@Override
public void run() {
try {
latch.await();
OneInstanceService one = OneInstanceService.getTest1();
if (one.i_am_has_state == 0) {
System.out.println("one.i_am_has_state == 0 process exit");
System.exit(0);
}
end.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.start();
}
latch.countDown();
end.await();
OneInstanceService.reset();
}
}
}
仅使用:
public int i_am_has_state;
运行结果是:
System.out.println("one.i_am_has_state == 0 process exit");
System.exit(0);
但修改代码底部:
volatile public int i_am_has_state;
要么
final public int i_am_has_state;
没有运行底部代码:
System.out.println("one.i_am_has_state == 0 process exit");
System.exit(0);
我的问题是:
DCL使用最后确定
DCL使用最终挥发性好
所以
在DCL中最终和挥发性的区别?
非常感谢你 !
最佳答案
final和volatile无法放在一起,因为它们是故意相反的。
或者您有一个静态字段,它在类init时初始化过:
static final Object x;
static {
x = ...
}
或者您有一个可变的静态字段,多个线程可以争用设置(您的情况)。
为了使双重检查惯用语言起作用,它必须是可变的(自jdk 1.5起使用新的可变语义)。从那时起,volatile就具有防止其他变量涉及的指令重新排序的内存屏障,这(以某种方式使我(现在不记得了……)使丑陋的DCL再次起作用...但并没有使其变得丑陋。
(我从来不需要使用DCL;没有DCL,因为
if(x==null)
是如此之快,所以同步仍然基本上没有竞争性。)