您当前的位置:首页 > 计算机 > 编程开发 > Java

Java 原子操作

时间:12-14来源:作者:点击数:

原子操作 - 计数器、域更新器

java.util.concurrent.atomic 包,可以在多线程环境下,无锁无阻塞的进行原子操作。原子类分为4种类型:计数器、域更新器、数组及复合变量。

计数器

  • AtomicBoolean:原子更新布尔值
  • AtomicInteger:原子更新整形值
  • AtomicLong:原子更新 Long 值
  • AtomicReference:原子更新引用值

AtomicInteger 常用方法

关键方法 说明
int addAndGet(int delta) 以原子方式将输入的数值与实例中的值(AtomicInteger里的value)相加,并返回结果
boolean compareAndSet(int expect, int update) 如果输入的数值等于预期值,则以原子方式将
int getAndIncrement() 以原子方式将当前值加1,注意:这里返回的是自增前的值,相当于i++。

域更新器

  • AtomicIntegerFieldUpdater:原子操作对象的整型的字段
  • AtomicLongFieldUpdater:原子操作对象的 Long 类型的字段
  • AtomicReferenceFieldUpdater:原子操作对象的引用字段

AtomicIntegerFieldUpdater 常用方法

关键方法 说明
static AtomicIntegerFieldUpdater newUpdater(Class<U> tclass, String fieldName) 创建一个 AtomicIntegerFieldUpdater
public int getAndIncrement(T obj) 更新指定对象的整型字段,将其值加一

原子操作 - 代码示例

int 累加

static volatile int j=0;
static Runnable run = new Runnable() {
 public void run() {
 for(int i=0;i<10000;i++)
 j++;
 }
};
public static void main(String[] arg) throws Exception
{
 for(int i=0;i<50;i++)
 new Thread(run).start();
 Thread.sleep(1000);
 System.out.println("j="+j);
}
AtomicInteger累加
static volatile AtomicInteger j=new AtomicInteger(0);
static Runnable run = new Runnable() {
 public void run() {
 for(int i=0;i<10000;i++)
 j.incrementAndGet();
 }
};
public static void main(String[] arg) throws Exception
{
 for(int i=0;i<50;i++)
 new Thread(run).start();
 Thread.sleep(1000);
 System.out.println("j="+j.get());
}

AtomicIntegerFieldUpdater
public class filedUpdater{
/*
1.必须用volatile修饰
2.不能是static变量
3.private protected 都可以通过原子域更新
*/
 public volatile int i;
 public static void main(String[] arg)
 {
 filedUpdaterf = new filedUpdater();
 f.i=99;
 AtomicIntegerFieldUpdater integerUpdate = AtomicIntegerFieldUpdater.newUpdater(filedUpdater.class,"i");
 System.out.println(integerUpdate.getAndIncrement(f));
 System.out.println(f.i);
 }
}

原子操作 - 数组、复合变量

数组

  • AtomicIntegerArray:支持原子操作的Integer数组
  • AtomicLongArray:支持原子操作的Long数组
  • AtomicReferenceArray :支持原子操作的Reference数组

AtomicIntegerArray 常用方法

关键方法 说明
int addAndGet(int i, int delta) 指定数组下标i对应的元素增加 delta,并返回最新值。
boolean compareAndSet(inti, int expect, int update) 对数组下标 i 的元素进行 CAS 操作,若下标i的值为 expect 则将值设置为 update。
int incrementAndGet(int i) 对数组下标 i 进行加1操作,加完之后返回最新值。

复合变量

  • AtomicStampedReference:引用类型和整型标识的复合变量,只有引用和整型完全相等才认为操作行为是合法的。
  • AtomicMarkableReference:引用类型和布尔值标识的复合变量,只有引用和布尔值完全相等才认为操作行为是合法的。

AtomicStampedReference 常用方法

关键方法 说明
AtomicStampedReference(V initialRef, int initialStamp) 构造函数,传入一个对象引用和整型标记。
boolean compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp) CAS 操作,只有期望的引用和期望的整型标记完全一致时,才能操作成功。
int getStamp() 返回整型标记。
V getReference() 返回对象引用。

数组操作

public static void main(String[] arg) throws Exception
{
 AtomicIntegerArraya = new AtomicIntegerArray(new int[]{1,2,3});
 System.out.println("a[0]="+a.addAndGet(0,9));
 System.out.println(a);
 a.compareAndSet(0,10,11);
 System.out.println(a);
}

AtomicStampedReference 解决 ABA 问题

public static void main(String[] arg) throws Exception
{
 String str="A"; int stamp;
 AtomicStampedReference stapRef = new AtomicStampedReference(str,0);
 stapRef.compareAndSet("A","B",stapRef.getStamp(),stapRef.getStamp() + 1);
 stapRef.compareAndSet("B","A",stapRef.getStamp(),stapRef.getStamp() + 1);
 System.out.println(stapRef.getReference()+" "+stapRef.getStamp());
}
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
上一篇:Java 并发容器 下一篇:Java 线程锁
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐