java 中没有 AtomicInteger 如何保证原子性?
how to assure atomicity without AtomicInteger in java?
假设 Java 6/7/8:
是否有机会在不使用例如AtomicInteger
?从我的小型研究来看,这似乎通常是不可能的,但是 integer/byte/char 操作本身是原子的 (source)。
显然,有 synchronized
但在这一点上我想避免它。所以问题是:我可以像 atomic(x++)
那样做吗?
您的选择是:
- 通过
synchronized
关键字的内部锁
- 使用来自
java.util.concurrent.locks
的显式锁来包装您想要使其成为原子的操作
我的建议是:如果你在做多线程编程,尽快从同步开始。原子性适用于小型数据类型,但一旦您想从不同线程访问 class 个实例,您就需要考虑同步,通过使用 synchronized
或显式操作锁。
虽然单个 int
读取和写入在它们不会使变量处于不一致状态的意义上是原子的,但这并不是关于原子性的唯一重要的事情。特别是现代 CPU 重新排序指令和缓存内存,因此对变量的更改可能对其他线程不可见(这可以通过向变量添加 volatile
关键字来解决。
另外,AtomicInteger
和朋友们也提供了由多个操作组成的操作,例如getAndIncrement()
方法,类似于使用后缀++
运算符。这包括一个读取和一个写入,如果你不同步或不使用AtomicInteger
,其他线程可能会访问读取和写入之间的变量。
如果你想从多个线程读写变量,那么你确实需要对变量施加一些原子性。您不能依赖本质上是原子的操作,因为变量的值可以由线程缓存。因此,一个线程中的更新可能不会被另一个线程看到。解决此问题的最简单方法是声明一个变量 volatile
以强制读取最新值。 java.util.concurrent 类 提供额外的功能和良好的性能。
假设 Java 6/7/8:
是否有机会在不使用例如AtomicInteger
?从我的小型研究来看,这似乎通常是不可能的,但是 integer/byte/char 操作本身是原子的 (source)。
显然,有 synchronized
但在这一点上我想避免它。所以问题是:我可以像 atomic(x++)
那样做吗?
您的选择是:
- 通过
synchronized
关键字的内部锁 - 使用来自
java.util.concurrent.locks
的显式锁来包装您想要使其成为原子的操作
我的建议是:如果你在做多线程编程,尽快从同步开始。原子性适用于小型数据类型,但一旦您想从不同线程访问 class 个实例,您就需要考虑同步,通过使用 synchronized
或显式操作锁。
虽然单个 int
读取和写入在它们不会使变量处于不一致状态的意义上是原子的,但这并不是关于原子性的唯一重要的事情。特别是现代 CPU 重新排序指令和缓存内存,因此对变量的更改可能对其他线程不可见(这可以通过向变量添加 volatile
关键字来解决。
另外,AtomicInteger
和朋友们也提供了由多个操作组成的操作,例如getAndIncrement()
方法,类似于使用后缀++
运算符。这包括一个读取和一个写入,如果你不同步或不使用AtomicInteger
,其他线程可能会访问读取和写入之间的变量。
如果你想从多个线程读写变量,那么你确实需要对变量施加一些原子性。您不能依赖本质上是原子的操作,因为变量的值可以由线程缓存。因此,一个线程中的更新可能不会被另一个线程看到。解决此问题的最简单方法是声明一个变量 volatile
以强制读取最新值。 java.util.concurrent 类 提供额外的功能和良好的性能。