FutureTask中使用UNSAFE.putOrderedInt而非直接赋值state的优势?
关于FutureTask.set方法中putOrderedInt的疑问解答
为什么不直接用state = NORMAL赋值?
直接赋值属于Java普通写操作,没有禁止重排序的语义。这段代码里,outcome = v是结果赋值,state = NORMAL是标记任务完成。如果用普通写,JVM可能对这两个操作重排序,导致其他线程先看到state变为NORMAL,但outcome还没完成赋值,进而出现"任务已完成但获取到错误/空结果"的问题。
使用putOrderedInt的优势
UNSAFE.putOrderedInt是轻量级的有序写操作,核心特性和优势如下:
- 保证操作顺序:它会禁止前面的写操作(比如
outcome = v)被重排序到该操作之后,确保其他线程只要看到state变为NORMAL,outcome一定已完成赋值,不会出现逻辑错误。 - 更低性能开销:相比volatile写(会立即把值刷新到主存,带来总线同步开销),putOrderedInt不会强制立即刷新到主存,仅保证最终对其他线程可见。后续的
finishCompletion()方法会唤醒等待线程,唤醒操作自带的内存屏障会确保前面的写操作对被唤醒线程可见;对于非等待线程,即使稍晚看到状态变化,也不会引发错误,同时避免了不必要的性能损耗。
内容的提问来源于stack exchange,提问作者lant
相关产品推荐
相关产品推荐

