- 主题:多线程下赋值重排序问题
假设有一个类
class Cat
{
int i;
String b;
List<Integer> l;
Set<Foot> feetSet;
}
现在有一个对象cat
在多线程下
多个线程对cat进行读,可能遍历l或者feetSet
有且仅一个线程对cat进行写,譬如将i,b,l,feetSet赋值为另外一个值
譬如
feetSet2 = new HashSet();
feetSet2.add(..);
..
cat.feetSet = feetSet2;
有的说法是,这会导致unsafe publication
即feetSet2可能还没初始化完成,但是因为重排序其地址就被读线程拿到了,结果一访问就出错抛异常了,大家怎么看?
有的说法是这些域加个volatile能解决,但是我感觉volatile只是让地址更加实时的暴露,而不是保证指向的内容初始化完成才暴露地址
--
FROM 122.115.231.*
没理解你什么意思
不过volatile针对的是地址,而不是对象吧
【 在 MyWorkLife 的大作中提到: 】
: 你理解得不太对
: volatile有内存屏障作用
:
--
FROM 122.115.231.*
set内部不会变化
只是担心对象本身还没初始化或者变动完成
后面的赋值操作被重排序到前面
地址就提前暴露给了其他线程了
【 在 oldwatch 的大作中提到: 】
: 这里要区分对cat对象成员的赋值操作和对对象的操作
:
: 对于对象而言,单纯的=赋值操作,有volatile修饰的话是原子的
: ...................
--
FROM 122.115.231.*
和原子性没啥关系吧
你要说原子性除非是下面三个语句整体原子性
feetSet2 = new HashSet();
feetSet2.add(..);
cat.feetSet = feetSet2;
而我担心的是重排序问题
也就是第三个在前两个语句全部完成之前执行
需要的是内存栅栏
不知道volatile可以满足条件不
【 在 javafish 的大作中提到: 】
: 这种场景volatile解千愁
: 当然你要先在本地完成一切对象初始化
: 然后一句赋值完活,volatile保证地址操作原子性
: ...................
--
FROM 111.199.98.*
...
我说的就是多线程场景下
A线程给对象里的域赋值
B线程读对象里这些域的问题啊
【 在 javafish 的大作中提到: 】
: 重排序是指相对于其他线程的变量值的可见性
: 可能因重排序而不可确定
: 线程内没这个问题
: ...................
--
FROM 111.199.98.*