takooya
2019-04-08 08:50
synchronized所修饰的内部代码是否会重排序
补充一个问题
之前工作的时候写单例模式,举例如下,主管非得让加volatile来修饰single,说如果不加会有重排序问题,从而导致空指针,但是看到大家的讨论和老师的回答,我觉得不需要加volatile,因为synchronized关键字已经保证了只会有一个线程进入创建单例对象的代码,当这个线程锁释放的时候,因为happens-before原则,其他线程拿到的单例一定是完整的,也就是说这个单例的属性一定是已经被赋值的,不会出现空指针问题,请问老师我的理解准确吗
public class ExampleSingle { private volatile static ExampleSingle single; ***一些属性 private ExampleSingle() { *** 假如这里对这些属性进行了赋值操作 } public static ExampleSingle getInstance() { if (single == null) { synchronized (ExampleSingle.class) { if (single == null) { single = new ExampleSingle(); } } } return single; } }
不会限制,被synchronized修饰的代码会被编译器或者处理器重排序。多个线程如果不加同步锁,重排序可能会导致可见性问题(线程A中代码顺序不一致可能导致线程B得到错误的结果,即使线程A符合as-if-serial语义),而如果加了同步锁,不会导致可见性问题,因为线程A的所有操作对于线程B来说都是可见的。synchronized的作用主要是两点:1.保证有序性:使多个线程之间有序执行,不会出现交叉执行。2.保证可见性:线程解锁前,必须把共享变量的最新值刷新到主内存中,线程加锁时,需要从主内存中重新读取最新值。
不会,它的作用是在多线程情况下的。单线程下重排序是不会影响执行结果的。
细说Java多线程之内存可见性
55908 学习 · 74 问题
相似问题