Java 原子操作
原子操作 - 计数器、域更新器
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());
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: Java 线程锁
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论