原子运算和多线程

最近我正在阅读一个教程,因为我遇到了一个声明,上面写着..

“Java语言规范保证读取或写入变量是原子操作(除非变量的类型为或)。类型或类型的操作变量,如果它们使用关键字声明,则它们才是原子的。longdoublelongdoublevolatile

AtomicInteger或者提供类似 、和原子的方法。AtomicLonggetAndDecrement()getAndIncrement()getAndSet()

我对上述说法有点困惑。你能不能澄清一下何时使用或类。AtomicIntegerAtomicLong


答案 1

做(作为)是一个原子操作。但 doing 不是原子操作,因为它需要读取 a 的值、递增和写入结果的 a。因此,如果您曾经实现线程安全计数器,则可以有两个线程同时读取值(例如 26),然后同时递增该值并发写入该值,从而产生 27,而不是 28。a = 28ainta++a++

AtomicInteger通过提供原子操作(如您列出的操作)来解决此问题。在我的示例中,您将使用例如,这将保证最终值为28而不是27。incrementAndGet()


答案 2

原子意味着操作完成,之间没有任何可能发生的事情。例如。getAndDecrement() 在 AtomicInteger 上,保证变量同时返回并递减。

如果它不是原子操作,则该值有可能递减(例如,从3减少到2),然后由另一个线程修改(例如,将其从2更改为5),然后返回为5。