Java多線程中的原子類屬性說(shuō)明
什么是原子類
什么是原子類
一度認(rèn)為原子是不可分割的最小單位,故原子類可以認(rèn)為其操作都是不可分割
為什么要有原子類
對(duì)多線程訪問(wèn)同一個(gè)變量,我們需要加鎖,而鎖是比較消耗性能的,JDk1.5之后,新增的原子操作類提供了一種用法簡(jiǎn)單、性能高效、線程安全地更新一個(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í)保證立即可見(jiàn)
- 字段的描述類型是與調(diào)用者與操作對(duì)象字段的關(guān)系一致。
- 也就是說(shuō)調(diào)用者能夠直接操作對(duì)象字段,那么就可以反射進(jìn)行原子操作。
- 對(duì)于父類的字段,子類是不能直接操作的,盡管子類可以訪問(wèn)父類的字段。
- 只能是實(shí)例變量,不能是類變量,也就是說(shuō)不能加static關(guān)鍵字。
- 只能是可修改變量,不能使final變量,因?yàn)閒inal的語(yǔ)義就是不可修改。
- 對(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多線程中的原子類屬性說(shuō)明的文章就介紹到這了,更多相關(guān)Java原子類屬性內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IDEA報(bào)錯(cuò)之前言中不允許有內(nèi)容問(wèn)題及解決
當(dāng)使用IntelliJ IDEA時(shí),可能會(huì)遇到報(bào)錯(cuò)信息“前言中不允許有內(nèi)容”,這通常是由于XML文件是以帶有BOM頭的UTF-8格式保存的,導(dǎo)致IDE的解析出錯(cuò),解決辦法是在IDEA中調(diào)整文件編碼設(shè)置為無(wú)BOM的UTF-8,然后用文本編輯器(如Notepad++)2024-10-10在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時(shí)間的簡(jiǎn)單實(shí)例
這篇文章介紹了在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時(shí)間的簡(jiǎn)單實(shí)例,有需要的朋友可以參考一下2013-09-09java實(shí)現(xiàn)雷霆戰(zhàn)機(jī)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)雷霆戰(zhàn)機(jī),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06關(guān)于java String中intern的深入講解
這篇文章主要給大家介紹了關(guān)于java String中intern的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04SpringCloud Alibaba 基本開(kāi)發(fā)框架搭建過(guò)程
這篇文章主要介紹了SpringCloud Alibaba 基本開(kāi)發(fā)框架搭建過(guò)程,開(kāi)發(fā)工具選用的idea,本文通過(guò)圖文實(shí)例相結(jié)合給大家分享搭建全過(guò)程,需要的朋友可以參考下2021-06-06SpringBoot集成企業(yè)微信開(kāi)發(fā)的實(shí)現(xiàn)
本文將詳細(xì)介紹如何使用?Spring?Boot?集成企業(yè)微信開(kāi)發(fā),通過(guò)企業(yè)微信?API?可以實(shí)現(xiàn)企業(yè)內(nèi)部的一些自動(dòng)化業(yè)務(wù)流程,提高工作效率,感興趣的可以了解一下2023-07-07使用java?-jar修改SpringBoot中application.properties的配置項(xiàng)
這篇文章主要介紹了使用java?-jar修改SpringBoot中application.properties的配置項(xiàng)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02