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