Skip to content

关于CAS操作的事例是否有问题? #2650

Open
@zhuqiming

Description

@zhuqiming

`private volatile int a;
public static void main(String[] args){
CasTest casTest=new CasTest();
new Thread(()->{
for (int i = 1; i < 5; i++) {
casTest.increment(i);
System.out.print(casTest.a+" ");
}
}).start();
new Thread(()->{
for (int i = 5 ; i <10 ; i++) {
casTest.increment(i);
System.out.print(casTest.a+" ");
}
}).start();
}

private void increment(int x){
while (true){
try {
long fieldOffset = unsafe.objectFieldOffset(CasTest.class.getDeclaredField("a"));
if (unsafe.compareAndSwapInt(this,fieldOffset,x-1,x))
break;
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}`
文章中给的事例代码,我警告本地运行发现并不符合预期的输出1,2,3,4,5,6,7,8,9;虽然原子操作保证对于a的修改不会出现并发问题,但是两个线程在调用 casTest.increment(i)后的 print方法打印a的时候,会有问题,结果是1,2,3,5,5,6,7,8,9,因为线程2在不符合条件的时候会一直死循环,当第一个线程修改a=4的时候,此时第二个线程会马上修改a=5,这个修改的命令,执行在线程1里的 System.out.print(casTest.a+" "); 这个之前,导致 第一个线程打印a的时候会打印出5,而非4

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions