Java多線程中的原子類屬性說明
什么是原子類
什么是原子類
一度認(rèn)為原子是不可分割的最小單位,故原子類可以認(rèn)為其操作都是不可分割
為什么要有原子類
對(duì)多線程訪問同一個(gè)變量,我們需要加鎖,而鎖是比較消耗性能的,JDk1.5之后,新增的原子操作類提供了一種用法簡單、性能高效、線程安全地更新一個(gè)變量的方式,這些類同樣位于JUC包下的atomic包下,發(fā)展到JDk1.8,該包下共有17個(gè)類,囊括了原子更新基本類型、原子更新數(shù)組、原子更新屬性、原子更新引用
java8新增原子類
DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder、Striped64
package 多線程.atomic.demo1;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Author: ruan
* Date: 2021/7/4 12:09
* @Description:
*/
public class Demo1 {
private static AtomicInteger sum = new AtomicInteger(0);
public static void inCreat(){
sum.incrementAndGet();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 100; j++) {
inCreat();
System.out.println(sum);
try {
Thread.sleep(200l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
原子更新基本類型
發(fā)展至JDk1.8,基本類型原子類有以下幾個(gè):
AtomicBoolean、AtomicInteger、AtomicLong、DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder
大致可以歸為3類
- AtomicBoolean、AtomicInteger、AtomicLong 元老級(jí)的原子更新,方法幾乎一模一樣
- DoubleAdder、LongAdder 對(duì)Double、Long的原子更新性能進(jìn)行優(yōu)化提升
- DoubleAccumulator、LongAccumulator 支持自定義運(yùn)算
package 多線程.atomic.demo1;
import java.util.concurrent.atomic.LongAccumulator;
/**
* @Author: ruan
* Date: 2021/7/4 12:20
* @Description:
*/
public class Demo2 {
public static void main(String[] args) {
LongAccumulator longAccumulator = new LongAccumulator((left,right)->
left > right ? left : right,0L
);
longAccumulator.accumulate(3l);
System.out.println(longAccumulator.get());
}
}
原子更新數(shù)組類型
AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
package 多線程.atomic.demo2;
import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* @Author: ruan
* Date: 2021/7/4 12:26
* @Description:
*/
public class Demo1 {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(arr);
int i = atomicIntegerArray.addAndGet(1, 2);
System.out.println(i);
//自定義計(jì)算
int i1 = atomicIntegerArray.accumulateAndGet(0, 2, ((left, right) ->
left > right ? left : right
));
System.out.println(i1);
}
}
原子更新屬性
原子地更新某個(gè)類里的某個(gè)字段時(shí),就需要使用原子更新字段類,Atomic包提供了以下4個(gè)類進(jìn)行原子字段更新
AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedReference、AtomicReferenceFieldUpdater
使用上述類的時(shí)候,必須遵循以下原則
- 字段必須是volatile類型的,在線程之間共享變量時(shí)保證立即可見
- 字段的描述類型是與調(diào)用者與操作對(duì)象字段的關(guān)系一致。
- 也就是說調(diào)用者能夠直接操作對(duì)象字段,那么就可以反射進(jìn)行原子操作。
- 對(duì)于父類的字段,子類是不能直接操作的,盡管子類可以訪問父類的字段。
- 只能是實(shí)例變量,不能是類變量,也就是說不能加static關(guān)鍵字。
- 只能是可修改變量,不能使final變量,因?yàn)閒inal的語義就是不可修改。
- 對(duì)于AtomicIntegerFieldUpdater和AtomicLongFieldUpdater只能修改int/long類型的字段,不能修改其包裝類型(Integer/Long)。
- 如果要修改包裝類型就需要使用AtomicReferenceFieldUpdater。
package 多線程.atomic.demo3;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
/**
* @Author: ruan
* Date: 2021/7/4 12:48
* @Description:
*/
public class Demo1 {
public static void main(String[] args) {
Student student = new Student("ruan", 18L);
AtomicLongFieldUpdater<Student> longFieldUpdater = AtomicLongFieldUpdater.newUpdater(Student.class, "age");
longFieldUpdater.compareAndSet(student,18L,20L);
System.out.println("age = " + student.getAge());
AtomicReferenceFieldUpdater<Student, String> objectObjectAtomicReferenceFieldUpdater = AtomicReferenceFieldUpdater.newUpdater(Student.class,String.class,"name");
objectObjectAtomicReferenceFieldUpdater.compareAndSet(student,"ruan","ruanxiangge");
System.out.println("name = " + student.getName());
}
}
class Student{
volatile String name;
volatile long age;
public Student(String name, long age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getAge() {
return age;
}
public void setAge(long age) {
this.age = age;
}
}
原子更新引用
- AtomicReference:用于對(duì)引用的原子更新
- AtomicMarkableReference:帶版本戳的原子引用類型,版本戳為boolean類型。
- AtomicStampedReference:帶版本戳的原子引用類型,版本戳為int類型。
package 多線程.atomic.demo4;
import java.util.concurrent.atomic.AtomicReference;
/**
* @Author: ruan
* Date: 2021/7/4 13:03
* @Description:
*/
public class Demo1 {
public static void main(String[] args) {
AtomicReference<Student> studentAtomicReference = new AtomicReference<>();
Student ruan = new Student(1L, "ruan");
Student rxg = new Student(2L, "rxg");
studentAtomicReference.set(ruan );
boolean b = studentAtomicReference.compareAndSet(ruan, rxg);
Student student = studentAtomicReference.get();
System.out.println(student.getName());
}
}
class Student{
private long id;
private String name;
public Student(long id, String name) {
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
到此這篇關(guān)于Java多線程中的原子類屬性說明的文章就介紹到這了,更多相關(guān)Java原子類屬性內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法
這篇文章主要介紹了java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Java+MySQL實(shí)現(xiàn)圖書管理系統(tǒng)(完整代碼)
這篇文章主要介紹了Java+MySQL實(shí)現(xiàn)圖書管理系統(tǒng)(完整代碼),本文給大家介紹的非常想詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
基于紅黑樹插入操作原理及java實(shí)現(xiàn)方法(分享)
下面小編就為大家分享一篇基于紅黑樹插入操作原理及java實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12
解決mapstruct在eclipse生成不了mapper的實(shí)現(xiàn)類問題
這篇文章主要介紹了解決mapstruct在eclipse生成不了mapper的實(shí)現(xiàn)類問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
SpringBoot2.x實(shí)現(xiàn)給Controller的RequestMapping添加統(tǒng)一前綴
這篇文章主要介紹了SpringBoot2.x實(shí)現(xiàn)給Controller的RequestMapping添加統(tǒng)一前綴,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Java模擬死鎖發(fā)生之演繹哲學(xué)家進(jìn)餐問題案例詳解
這篇文章主要介紹了Java模擬死鎖發(fā)生之演繹哲學(xué)家進(jìn)餐問題,結(jié)合具體演繹哲學(xué)家進(jìn)餐問題的案例形式詳細(xì)分析了死鎖機(jī)制與原理,需要的朋友可以參考下2019-10-10
SpringCloud搭建netflix-eureka微服務(wù)集群的過程詳解
這篇文章主要介紹了SpringCloud搭建netflix-eureka微服務(wù)集群的過程詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
Mybatis中的config.xml配置文件詳細(xì)解析
這篇文章主要介紹了詳解Mybatis-config.xml配置文件,需要的朋友可以參考下2017-12-12
解析SpringCloud簡介與微服務(wù)架構(gòu)
這篇文章主要介紹了SpringCloud簡介與微服務(wù)架構(gòu),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01

