1.简介
- JDK1.5开始提供了java.util.concurrent.atomic包,这个包中的原子类提供了一种用法简单、性能高效、线程安全的更新变量的方式。
- 包中共计12个类,分属于4种类型:
- 原子更新基本类型
- 原子更新数组
- 原子更新引用类型
- 原子更新属性(类的字段)
- 实现方式 基本都是使用Unsafe实现的包装类。
- AtomicBoolean:原子更新布尔类型。
- AtomicInteger:原子更新整型。
- AtomicLong:原子更新长整型。
- AtomicIntegerArray:原子更新整型数组里的元素。
- AtomicLongArray:原子更新长整型数组里面的元素。
- AtomicReferenceArray:原子更新引用类型数组里的元素。
- AtomicReference:原子更新引用类型。
- AtomicReferenceFieldUpdater:原子更新引用类型里的字段。
- AtomicMarkableReference:原子更新带有标记位的引用类型。 可以原子更新一个布尔类型的标记位和引用类型。构造方法是:AtomicMarkableReference (V initialRef,boolean initialMark) 。
- AtomicIntegerFieldUpdater:原子更新整型字段的更新器。
- AtomicLongFieldUpdater:原子更新长整型字段的更新器。
- AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更新数据和数据的版本号,可以解决使用CAS进行原子更新时可能出现的ABA问题。
-
说明:原子更新字段类需要两步:
- 创建更新器。因为原子字段更新类都是抽象类,每次使用的时候必须使用静态方法newUpdater()方法创建一个更新器,并且设置想要更新的类和属性。
- 更新类的字段(属性)必须使用public volatile修饰符。
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;
public class Main {
public static void main(String[] args){
//原子更新基本类型
System.out.println("-----原子更新基本类型----");
AtomicInteger ai=new AtomicInteger(1);
System.out.println(ai.getAndAdd(1));
System.out.println(ai.get());
//原子更新数组
System.out.println("-----原子更新数组----");
int[] a={1,2,3};
AtomicIntegerArray array=new AtomicIntegerArray(a);
array.getAndSet(0,6);
System.out.println(array.get(0));
System.out.println(a[0]);
//原子更新引用
System.out.println("-----原子更新引用----");
AtomicReference<User> are=new AtomicReference<>();
User user1=new User("cxh",22);
are.set(user1);
User user2=new User("caoxiaohong",24);
are.compareAndSet(user1,user2);
System.out.println(are.get().getName());
System.out.println(are.get().getAge());
//原子更新字段
System.out.println("-----原子更新字段----");
AtomicIntegerFieldUpdater<Profile> aifu=AtomicIntegerFieldUpdater.newUpdater(Profile.class,"age");//创建更新器
Profile pro=new Profile("Cxh",25);
System.out.println(aifu.getAndIncrement(pro));
System.out.println(aifu.get(pro));
}
//此类用于原子更新引用
static class User{
String name;
int age;
User(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//此类用于原子更新类字段
static class Profile{
String name;
public volatile int age;//类型必须是public volatile 类型
Profile(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
- AtomicIntegerArray:原子更新整型数组里的元素。
- AtomicLongArray:原子更新长整型数组里面的元素。
- AtomicReferenceArray:原子更新引用类型数组里的元素。
- AtomicReference:原子更新引用类型。
- AtomicReferenceFieldUpdater:原子更新引用类型里的字段。
- AtomicMarkableReference:原子更新带有标记位的引用类型。 可以原子更新一个布尔类型的标记位和引用类型。构造方法是:AtomicMarkableReference (V initialRef,boolean initialMark) 。
- AtomicIntegerFieldUpdater:原子更新整型字段的更新器。
- AtomicLongFieldUpdater:原子更新长整型字段的更新器。
- AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更新数据和数据的版本号,可以解决使用CAS进行原子更新时可能出现的ABA问题。
-
说明:原子更新字段类需要两步:
- 创建更新器。因为原子字段更新类都是抽象类,每次使用的时候必须使用静态方法newUpdater()方法创建一个更新器,并且设置想要更新的类和属性。
- 更新类的字段(属性)必须使用public volatile修饰符。
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;
public class Main {
public static void main(String[] args){
//原子更新基本类型
System.out.println("-----原子更新基本类型----");
AtomicInteger ai=new AtomicInteger(1);
System.out.println(ai.getAndAdd(1));
System.out.println(ai.get());
//原子更新数组
System.out.println("-----原子更新数组----");
int[] a={1,2,3};
AtomicIntegerArray array=new AtomicIntegerArray(a);
array.getAndSet(0,6);
System.out.println(array.get(0));
System.out.println(a[0]);
//原子更新引用
System.out.println("-----原子更新引用----");
AtomicReference<User> are=new AtomicReference<>();
User user1=new User("cxh",22);
are.set(user1);
User user2=new User("caoxiaohong",24);
are.compareAndSet(user1,user2);
System.out.println(are.get().getName());
System.out.println(are.get().getAge());
//原子更新字段
System.out.println("-----原子更新字段----");
AtomicIntegerFieldUpdater<Profile> aifu=AtomicIntegerFieldUpdater.newUpdater(Profile.class,"age");//创建更新器
Profile pro=new Profile("Cxh",25);
System.out.println(aifu.getAndIncrement(pro));
System.out.println(aifu.get(pro));
}
//此类用于原子更新引用
static class User{
String name;
int age;
User(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//此类用于原子更新类字段
static class Profile{
String name;
public volatile int age;//类型必须是public volatile 类型
Profile(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
- AtomicIntegerFieldUpdater:原子更新整型字段的更新器。
- AtomicLongFieldUpdater:原子更新长整型字段的更新器。
- AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于原子的更新数据和数据的版本号,可以解决使用CAS进行原子更新时可能出现的ABA问题。
-
说明:原子更新字段类需要两步:
- 创建更新器。因为原子字段更新类都是抽象类,每次使用的时候必须使用静态方法newUpdater()方法创建一个更新器,并且设置想要更新的类和属性。
- 更新类的字段(属性)必须使用public volatile修饰符。
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;
public class Main {
public static void main(String[] args){
//原子更新基本类型
System.out.println("-----原子更新基本类型----");
AtomicInteger ai=new AtomicInteger(1);
System.out.println(ai.getAndAdd(1));
System.out.println(ai.get());
//原子更新数组
System.out.println("-----原子更新数组----");
int[] a={1,2,3};
AtomicIntegerArray array=new AtomicIntegerArray(a);
array.getAndSet(0,6);
System.out.println(array.get(0));
System.out.println(a[0]);
//原子更新引用
System.out.println("-----原子更新引用----");
AtomicReference<User> are=new AtomicReference<>();
User user1=new User("cxh",22);
are.set(user1);
User user2=new User("caoxiaohong",24);
are.compareAndSet(user1,user2);
System.out.println(are.get().getName());
System.out.println(are.get().getAge());
//原子更新字段
System.out.println("-----原子更新字段----");
AtomicIntegerFieldUpdater<Profile> aifu=AtomicIntegerFieldUpdater.newUpdater(Profile.class,"age");//创建更新器
Profile pro=new Profile("Cxh",25);
System.out.println(aifu.getAndIncrement(pro));
System.out.println(aifu.get(pro));
}
//此类用于原子更新引用
static class User{
String name;
int age;
User(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//此类用于原子更新类字段
static class Profile{
String name;
public volatile int age;//类型必须是public volatile 类型
Profile(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;
public class Main {
public static void main(String[] args){
//原子更新基本类型
System.out.println("-----原子更新基本类型----");
AtomicInteger ai=new AtomicInteger(1);
System.out.println(ai.getAndAdd(1));
System.out.println(ai.get());
//原子更新数组
System.out.println("-----原子更新数组----");
int[] a={1,2,3};
AtomicIntegerArray array=new AtomicIntegerArray(a);
array.getAndSet(0,6);
System.out.println(array.get(0));
System.out.println(a[0]);
//原子更新引用
System.out.println("-----原子更新引用----");
AtomicReference<User> are=new AtomicReference<>();
User user1=new User("cxh",22);
are.set(user1);
User user2=new User("caoxiaohong",24);
are.compareAndSet(user1,user2);
System.out.println(are.get().getName());
System.out.println(are.get().getAge());
//原子更新字段
System.out.println("-----原子更新字段----");
AtomicIntegerFieldUpdater<Profile> aifu=AtomicIntegerFieldUpdater.newUpdater(Profile.class,"age");//创建更新器
Profile pro=new Profile("Cxh",25);
System.out.println(aifu.getAndIncrement(pro));
System.out.println(aifu.get(pro));
}
//此类用于原子更新引用
static class User{
String name;
int age;
User(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//此类用于原子更新类字段
static class Profile{
String name;
public volatile int age;//类型必须是public volatile 类型
Profile(String name,int age){
this.name=name;
this.age=age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
输出结果:
-----原子更新基本类型----
1
2
-----原子更新数组----
6
1
-----原子更新引用----
caoxiaohong
24
-----原子更新字段----
25
26
Process finished with exit code 0
参考书籍:《Java并发编程的艺术》
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。