Java中的AtomicInteger示例
Java中的java.util.concurrent.atomic软件包具有支持无锁原子操作的类。这意味着,对于整数,长整数,布尔值以及对象引用和数组,无需使用显式同步或者锁定,就可以保证使用该程序包中包含的类的原子性。在本文中,我们将讨论Java中的此类AtomicInteger之一,该类提供可以自动更新的int值。
Java中的AtomicInteger
AtomicInteger类是java.util.concurrent.atomic包的一部分,提供了获取,设置,递增,更新,比较int值的方法,该方法作为原子操作,也无需使用锁或者synced关键字来调节多个线程对共享变量的访问。
原子类使用CAS(比较和交换)来确保使用非阻塞算法的数据完整性。这就是为什么这些类比锁定快的原因,在一个线程获得对象锁定而其他线程被阻塞的情况下,锁定比锁定快。
Java AtomicInteger构造函数
AtomicInteger类中有两个构造函数。
AtomicInteger()–创建一个初始值为0的新AtomicInteger。
AtomicInteger(int initialValue)–创建一个使用给定初始值初始化的新AtomicInteger。
AtomicInteger Java示例
常见用途之一是使用AtomicInteger提供原子递增计数器。为了这个目的,可以使用incrementAndGet()方法来原子地增加当前值。
使用AtomicInteger以原子方式递增的计数器
public class AtomicIntExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
AtomicInteger atomicInt = new AtomicInteger();
for(int i = 0; i < 10; i++){
executor.submit(()->System.out.println("Counter- " + atomicInt.incrementAndGet()));
}
executor.shutdown();
}
}
输出:
Counter- 1 Counter- 2 Counter- 3 Counter- 4 Counter- 5 Counter- 6 Counter- 7 Counter- 8 Counter- 9 Counter- 10
在上面的示例中,Runnable被实现为lambda表达式。如果我们更喜欢Runnable实现,则这里的旧方法是同一示例。
public class AtomicIntExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
AtomicInteger atomicInt = new AtomicInteger();
CounterRunnable runnableTask = new CounterRunnable(atomicInt);
for(int i = 0; i < 10; i++){
executor.submit(runnableTask);
}
executor.shutdown();
}
}
class CounterRunnable implements Runnable{
AtomicInteger atomicInt;
CounterRunnable(AtomicInteger atomicInt){
this.atomicInt = atomicInt;
}
@Override
public void run() {
System.out.println("Counter- " + atomicInt.incrementAndGet());
}
}
AtomicInteger类中的方法
Java AtomicInteger类中的一些原子方法如下:
addAndGet(int delta)–以原子方式将给定值添加到当前值。
compareAndSet(int Expect,int update)–如果当前值==预期值,则以原子方式将该值设置为给定的更新值。
getAndDecrement()–以原子方式将当前值减一。
getAndIncrement()–以原子方式将当前值增加一。
getAndSet(int newValue)–以原子方式设置为给定值并返回旧值。
getAndUpdate(IntUnaryOperator updateFunction)–使用应用给定函数的结果以原子方式更新当前值,并返回先前的值。
IncrementAndGet()–以原子方式将当前值增加一。
使用AtomicInteger比较和设置值
我们可以使用compareAndSet()方法比较并设置值,该方法接受两个参数的期望值并进行更新。如果期望值等于AtomicInteger实例的当前值,则将更新该值。如果成功,则返回true。错误返回表示实际值不等于期望值。
public class AtomicIntExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
AtomicInteger atomicInt = new AtomicInteger(0);
for(int i = 1; i <= 10; i++){
// delay between each update submission
try {
TimeUnit.MILLISECONDS.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
executor.submit(new RunnableTask(atomicInt, atomicInt.get(), i));
}
System.out.println("Updated value- " + atomicInt.get());
executor.shutdown();
}
}
class RunnableTask implements Runnable{
AtomicInteger atomicInt;
int expectedVal;
int newVal;
RunnableTask(AtomicInteger atomicInt, int expectedVal, int newVal){
this.atomicInt = atomicInt;
this.expectedVal = expectedVal;
this.newVal = newVal;
}
@Override
public void run() {
System.out.println("Value updated- " + atomicInt.compareAndSet(expectedVal, newVal));
}
}
输出:
Value updated- true Value updated- true Value updated- true Value updated- true Value updated- true Value updated- true Value updated- true Value updated- true Value updated- true Value updated- true Updated value- 10

