当前位置:网站首页>Atomic atomic class
Atomic atomic class
2022-07-25 12:12:00 【JackLi0812】
1 Atomic Introduction to atomic class
Atomic Translated into Chinese is the meaning of atom . In Chemistry , We know that atoms are the smallest unit of general matter , It's inseparable in chemical reactions . Here we are Atomic An operation is uninterruptible . Even when multiple threads are executing together , Once an operation begins , It won't be interfered by other threads .
therefore , The so-called atomic class is simply to have atoms / A class of atomic operating characteristics .
Contract issuance java.util.concurrent The atomic classes of are stored in java.util.concurrent.atomic Next , As shown in the figure below .

Depending on the data type of the operation , Can be JUC The atomic classes in the package are divided into 4 class
Basic types
Update the basic types using atoms
- AtomicInteger: Integer atom class
- AtomicLong: Long integer atom class
- AtomicBoolean : Boolean atom class
An array type
Update an element in an array by using atoms
- AtomicIntegerArray: Integer array atomic class
- AtomicLongArray: Long integer array atomic class
- AtomicReferenceArray : Reference type array atomic class
Reference type
- AtomicReference: Reference type atomic class
- AtomicMarkableReference: Atom update reference types with tags . This class will boolean Tags are associated with references ,
It can also solve the problem of using CAS What may occur when atomic updates are made ABA problem . - AtomicStampedReference : Atomic update reference type with version number . This class associates integer values with references , It can be used to solve the update data of atoms and the version number of data , It can solve the problem of using CAS What may occur when atomic updates are made ABA problem .
Object's property modification type
- AtomicIntegerFieldUpdater: Atom update integer field updater
- AtomicLongFieldUpdater: Atom update long field updater
- AtomicReferenceFieldUpdater: Atom updates the fields in the reference type
correct : AtomicMarkableReference It can't be solved ABA problem issue#626
/** AtomicMarkableReference Is the one boolean The value is marked whether there is any change , The essence is that it has only two version numbers ,true and false, When modifying, switch back and forth between the two version numbers , This will not solve ABA The problem of , It just reduces ABA It's just the probability of problems @author : Jack Li @Date : 2020/1/17 14:41 */
public class SolveABAByAtomicMarkableReference {
private static AtomicMarkableReference atomicMarkableReference = new AtomicMarkableReference(100, false);
public static void main(String[] args) {
Thread refT1 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
atomicMarkableReference.compareAndSet(100, 101, atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
atomicMarkableReference.compareAndSet(101, 100, atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
});
Thread refT2 = new Thread(() -> {
boolean marked = atomicMarkableReference.isMarked();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean c3 = atomicMarkableReference.compareAndSet(100, 101, marked, !marked);
System.out.println(c3); // return true, It should actually return to false
});
refT1.start();
refT2.start();
}
}
CAS ABA problem
- describe : The first thread gets the variable x Value A, Then Barbara did something else , In short, I just got the variables x Value A. During this time, the second thread also gets the variable x Value A, And then we put the variables x To change the value of B, Then Barbara did something else , Finally, the variable x The value of a A ( It's equivalent to restoring ). After that, the first thread finally changed the variable x The operation of , But at this point, the variable x The value of the or A, therefore compareAndSet The operation was successful .
- Example description ( It may not be appropriate , But it's easy to understand ): Beginning of the year , Cash is zero , Then he made three million through normal labor , Then normal consumption ( Like buying a house ) Three million . end of the year , Although there is no cash income ( It may have become another form ), But making money is a fact , Still have to pay taxes !
- Code example ( With
AtomicIntegerFor example )
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerDefectDemo {
public static void main(String[] args) {
defectOfABA();
}
static void defectOfABA() {
final AtomicInteger atomicInteger = new AtomicInteger(1);
Thread coreThread = new Thread(
() -> {
final int currentValue = atomicInteger.get();
System.out.println(Thread.currentThread().getName() + " ------ currentValue=" + currentValue);
// The purpose of this paragraph : Simulate the time spent processing other businesses
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean casResult = atomicInteger.compareAndSet(1, 2);
System.out.println(Thread.currentThread().getName()
+ " ------ currentValue=" + currentValue
+ ", finalValue=" + atomicInteger.get()
+ ", compareAndSet Result=" + casResult);
}
);
coreThread.start();
// The purpose of this paragraph : In order to make coreThread The thread runs first
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread amateurThread = new Thread(
() -> {
int currentValue = atomicInteger.get();
boolean casResult = atomicInteger.compareAndSet(1, 2);
System.out.println(Thread.currentThread().getName()
+ " ------ currentValue=" + currentValue
+ ", finalValue=" + atomicInteger.get()
+ ", compareAndSet Result=" + casResult);
currentValue = atomicInteger.get();
casResult = atomicInteger.compareAndSet(2, 1);
System.out.println(Thread.currentThread().getName()
+ " ------ currentValue=" + currentValue
+ ", finalValue=" + atomicInteger.get()
+ ", compareAndSet Result=" + casResult);
}
);
amateurThread.start();
}
}
The output is as follows :
Thread-0 ------ currentValue=1
Thread-1 ------ currentValue=1, finalValue=2, compareAndSet Result=true
Thread-1 ------ currentValue=2, finalValue=1, compareAndSet Result=true
Thread-0 ------ currentValue=1, finalValue=2, compareAndSet Result=true
Let's introduce these atomic classes in detail .
2 Basic type atomic class
2.1 Introduction to basic types and atomic classes
Update the basic types using atoms
- AtomicInteger: Integer atom class
- AtomicLong: Long integer atom class
- AtomicBoolean : Boolean atom class
The methods provided by the above three classes are almost the same , So here we are AtomicInteger Introduce... As an example .
AtomicInteger Class common methods
public final int get() // Get the current value
public final int getAndSet(int newValue)// Get the current value , And set the new value
public final int getAndIncrement()// Get the current value , And self increase
public final int getAndDecrement() // Get the current value , And reduce
public final int getAndAdd(int delta) // Get the current value , And add the expected value
boolean compareAndSet(int expect, int update) // If the value entered is equal to the expected value , Set the value to the input value in atomic mode (update)
public final void lazySet(int newValue)// The final setting is newValue, Use lazySet After setting, other threads may still be able to read the old values in a short period of time .
2.2 AtomicInteger Common methods use
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
int temvalue = 0;
AtomicInteger i = new AtomicInteger(0);
temvalue = i.getAndSet(3);
System.out.println("temvalue:" + temvalue + "; i:" + i);//temvalue:0; i:3
temvalue = i.getAndIncrement();
System.out.println("temvalue:" + temvalue + "; i:" + i);//temvalue:3; i:4
temvalue = i.getAndAdd(5);
System.out.println("temvalue:" + temvalue + "; i:" + i);//temvalue:4; i:9
}
}
2.3 Advantages of basic data type atomic class
Through a simple example, let's take a look at the advantages of the basic data type atomic class
① Multithreading environment does not use atomic classes to ensure thread safety ( Basic data type )
class Test {
private volatile int count = 0;
// For thread safe execution count++, It needs to be locked
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
② Multithreading environment uses atomic classes to ensure thread safety ( Basic data type )
class Test2 {
private AtomicInteger count = new AtomicInteger();
public void increment() {
count.incrementAndGet();
}
// Use AtomicInteger after , No need to lock , Thread safety can also be achieved .
public int getCount() {
return count.get();
}
}
2.4 AtomicInteger Simple analysis of thread safety principle
AtomicInteger Class part of the source code :
// setup to use Unsafe.compareAndSwapInt for updates( Provide... During update operation “ Compare and replace ” The role of )
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex); }
}
private volatile int value;
AtomicInteger Class mainly uses CAS (compare and swap) + volatile and native Method to ensure atomic operation , To avoid synchronized The high cost of , Greatly improved execution efficiency .
CAS The principle is to compare the expected value with the original value , If it is the same, update it to a new value .UnSafe Class objectFieldOffset() A method is a local method , This method is used to get “ The value of the original ” Memory address of . in addition value It's a volatile Variable , Visible in memory , therefore JVM It can guarantee that any thread can always get the latest value of this variable at any time .
3 Array type, atomic class
3.1 Array type atomic class introduction
Update an element in an array by using atoms
- AtomicIntegerArray: Shape array atomic class
- AtomicLongArray: Long shape array atomic class
- AtomicReferenceArray : Reference type array atomic class
The methods provided by the above three classes are almost the same , So here we are AtomicIntegerArray Introduce... As an example .
AtomicIntegerArray Class common methods
public final int get(int i) // obtain index=i The value of the location element
public final int getAndSet(int i, int newValue)// return index=i The current value of the position , And set it to the new value :newValue
public final int getAndIncrement(int i)// obtain index=i The value of the location element , And let the elements in this position increase by themselves
public final int getAndDecrement(int i) // obtain index=i The value of the location element , And let the elements in this position reduce themselves
public final int getAndAdd(int i, int delta) // obtain index=i The value of the location element , And add the expected value
boolean compareAndSet(int i, int expect, int update) // If the value entered is equal to the expected value , In the form of atoms index=i The element value of the position is set to the input value (update)
public final void lazySet(int i, int newValue)// Final take index=i The element of the location is set to newValue, Use lazySet After setting, other threads may still be able to read the old values in a short period of time .
3.2 AtomicIntegerArray Common methods use
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
int temvalue = 0;
int[] nums = {
1, 2, 3, 4, 5, 6 };
AtomicIntegerArray i = new AtomicIntegerArray(nums);
for (int j = 0; j < nums.length; j++) {
System.out.println(i.get(j));
}
temvalue = i.getAndSet(0, 2);
System.out.println("temvalue:" + temvalue + "; i:" + i);
temvalue = i.getAndIncrement(0);
System.out.println("temvalue:" + temvalue + "; i:" + i);
temvalue = i.getAndAdd(0, 5);
System.out.println("temvalue:" + temvalue + "; i:" + i);
}
}
4 Reference type atomic class
4.1 Introduction to reference type atomic class
A primitive type atomic class can only update one variable , If you need atoms to update multiple variables , Need to use Reference type atomic class .
- AtomicReference: Reference type atomic class
- AtomicStampedReference: Atomic update reference type with version number . This class associates integer values with references , It can be used to solve the update data of atoms and the version number of data , It can solve the problem of using CAS What may occur when atomic updates are made ABA problem .
- AtomicMarkableReference : Atom update reference types with tags . This class will boolean Tags are associated with references ,
It can also solve the problem of using CAS What may occur when atomic updates are made ABA problem .
The methods provided by the above three classes are almost the same , So here we are AtomicReference Introduce... As an example .
4.2 AtomicReference Class usage examples
import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceTest {
public static void main(String[] args) {
AtomicReference<Person> ar = new AtomicReference<Person>();
Person person = new Person("SnailClimb", 22);
ar.set(person);
Person updatePerson = new Person("Daisy", 20);
ar.compareAndSet(person, updatePerson);
System.out.println(ar.get().getName());
System.out.println(ar.get().getAge());
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
The above code first creates a Person object , And then put Person The object is set to AtomicReference In the object , And then call compareAndSet Method , This is through CAS The operation setting ar. If ar The value of is person Words , Set it to updatePerson. Principle of realization and AtomicInteger Class compareAndSet In the same way . After running the above code, the output is as follows :
Daisy
20
4.3 AtomicStampedReference Class usage examples
import java.util.concurrent.atomic.AtomicStampedReference;
public class AtomicStampedReferenceDemo {
public static void main(String[] args) {
// Instantiation 、 Take the current value and stamp value
final Integer initialRef = 0, initialStamp = 0;
final AtomicStampedReference<Integer> asr = new AtomicStampedReference<>(initialRef, initialStamp);
System.out.println("currentValue=" + asr.getReference() + ", currentStamp=" + asr.getStamp());
// compare and set
final Integer newReference = 666, newStamp = 999;
final boolean casResult = asr.compareAndSet(initialRef, newReference, initialStamp, newStamp);
System.out.println("currentValue=" + asr.getReference()
+ ", currentStamp=" + asr.getStamp()
+ ", casResult=" + casResult);
// Get the current value and the current stamp value
int[] arr = new int[1];
final Integer currentValue = asr.get(arr);
final int currentStamp = arr[0];
System.out.println("currentValue=" + currentValue + ", currentStamp=" + currentStamp);
// Set separately stamp value
final boolean attemptStampResult = asr.attemptStamp(newReference, 88);
System.out.println("currentValue=" + asr.getReference()
+ ", currentStamp=" + asr.getStamp()
+ ", attemptStampResult=" + attemptStampResult);
// Reset the current value and stamp value
asr.set(initialRef, initialStamp);
System.out.println("currentValue=" + asr.getReference() + ", currentStamp=" + asr.getStamp());
// [ It is not recommended to use , Unless the meaning of the note is clear ] weak compare and set
// confused !weakCompareAndSet This method will eventually call compareAndSet Method .[ edition : jdk-8u191]
// But the note says "May fail spuriously and does not provide ordering guarantees,
// so is only rarely an appropriate alternative to compareAndSet."
// todo It feels like it could be jvm Through the method name in native There is forwarding in the method
final boolean wCasResult = asr.weakCompareAndSet(initialRef, newReference, initialStamp, newStamp);
System.out.println("currentValue=" + asr.getReference()
+ ", currentStamp=" + asr.getStamp()
+ ", wCasResult=" + wCasResult);
}
}
The output is as follows :
currentValue=0, currentStamp=0
currentValue=666, currentStamp=999, casResult=true
currentValue=666, currentStamp=999
currentValue=666, currentStamp=88, attemptStampResult=true
currentValue=0, currentStamp=0
currentValue=666, currentStamp=999, wCasResult=true
4.4 AtomicMarkableReference Class usage examples
import java.util.concurrent.atomic.AtomicMarkableReference;
public class AtomicMarkableReferenceDemo {
public static void main(String[] args) {
// Instantiation 、 Take the current value and mark value
final Boolean initialRef = null, initialMark = false;
final AtomicMarkableReference<Boolean> amr = new AtomicMarkableReference<>(initialRef, initialMark);
System.out.println("currentValue=" + amr.getReference() + ", currentMark=" + amr.isMarked());
// compare and set
final Boolean newReference1 = true, newMark1 = true;
final boolean casResult = amr.compareAndSet(initialRef, newReference1, initialMark, newMark1);
System.out.println("currentValue=" + amr.getReference()
+ ", currentMark=" + amr.isMarked()
+ ", casResult=" + casResult);
// Get the current value and the current mark value
boolean[] arr = new boolean[1];
final Boolean currentValue = amr.get(arr);
final boolean currentMark = arr[0];
System.out.println("currentValue=" + currentValue + ", currentMark=" + currentMark);
// Set separately mark value
final boolean attemptMarkResult = amr.attemptMark(newReference1, false);
System.out.println("currentValue=" + amr.getReference()
+ ", currentMark=" + amr.isMarked()
+ ", attemptMarkResult=" + attemptMarkResult);
// Reset the current value and mark value
amr.set(initialRef, initialMark);
System.out.println("currentValue=" + amr.getReference() + ", currentMark=" + amr.isMarked());
// [ It is not recommended to use , Unless the meaning of the note is clear ] weak compare and set
// confused !weakCompareAndSet This method will eventually call compareAndSet Method .[ edition : jdk-8u191]
// But the note says "May fail spuriously and does not provide ordering guarantees,
// so is only rarely an appropriate alternative to compareAndSet."
// todo It feels like it could be jvm Through the method name in native There is forwarding in the method
final boolean wCasResult = amr.weakCompareAndSet(initialRef, newReference1, initialMark, newMark1);
System.out.println("currentValue=" + amr.getReference()
+ ", currentMark=" + amr.isMarked()
+ ", wCasResult=" + wCasResult);
}
}
The output is as follows :
currentValue=null, currentMark=false
currentValue=true, currentMark=true, casResult=true
currentValue=true, currentMark=true
currentValue=true, currentMark=false, attemptMarkResult=true
currentValue=null, currentMark=false
currentValue=true, currentMark=true, wCasResult=true
5 Object property modification type atomic class
5.1 Object attribute modification type atomic class introduction
If you need an atom to update a field in a class , You need to use the properties of the object to modify the type atomic class .
- AtomicIntegerFieldUpdater: Atom update shaper field updater
- AtomicLongFieldUpdater: Atom update long shape field updater
- AtomicReferenceFieldUpdater : The atom updates the updater of the field in the reference type
It takes two steps to update the properties of an object atomically . First step , Because the object's attribute modification type atomic classes are abstract classes , So every time you use it, you have to use static methods newUpdater() Create an updater , And you need to set the classes and properties you want to update . The second step , Updated object properties must use public volatile Modifier .
The methods provided by the above three classes are almost the same , So here we are AtomicIntegerFieldUpdater Introduce... As an example .
5.2 AtomicIntegerFieldUpdater Class usage examples
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public class AtomicIntegerFieldUpdaterTest {
public static void main(String[] args) {
AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");
User user = new User("Java", 22);
System.out.println(a.getAndIncrement(user));// 22
System.out.println(a.get(user));// 23
}
}
class User {
private String name;
public volatile int age;
public User(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Output results :
22
23
边栏推荐
- Learning to pre train graph neural networks
- 投屏收费背后:爱奇艺季度盈利,优酷急了?
- [dark horse morning post] eBay announced its shutdown after 23 years of operation; Wei Lai throws an olive branch to Volkswagen CEO; Huawei's talented youth once gave up their annual salary of 3.6 mil
- A beautiful gift for girls from programmers, H5 cube, beautiful, exquisite, HD
- 【图攻防】《Backdoor Attacks to Graph Neural Networks 》(SACMAT‘21)
- php curl post Length Required 错误设置header头
- 【GCN-RS】Learning Explicit User Interest Boundary for Recommendation (WWW‘22)
- GPT plus money (OpenAI CLIP,DALL-E)
- 通过Referer请求头实现防盗链
- 【AI4Code】《Unified Pre-training for Program Understanding and Generation》 NAACL 2021
猜你喜欢

Pycharm connects to the remote server SSH -u reports an error: no such file or directory

brpc源码解析(一)—— rpc服务添加以及服务器启动主要过程

Web programming (II) CGI related

Zero-Shot Image Retrieval(零样本跨模态检索)

Brpc source code analysis (VI) -- detailed explanation of basic socket

图神经网络用于推荐系统问题(IMP-GCN,LR-GCN)

【GCN-RS】Are Graph Augmentations Necessary? Simple Graph Contrastive Learning for RS (SIGIR‘22)

硬件连接服务器 tcp通讯协议 gateway

Learning to Pre-train Graph Neural Networks(图预训练与微调差异)

Go garbage collector Guide
随机推荐
奉劝那些刚参加工作的学弟学妹们:要想进大厂,这些并发编程知识是你必须要掌握的!完整学习路线!!(建议收藏)
微信公众号开发 入手
Video Caption(跨模态视频摘要/字幕生成)
Pycharm connects to the remote server SSH -u reports an error: no such file or directory
Zero-Shot Image Retrieval(零样本跨模态检索)
Meta-learning(元学习与少样本学习)
Learning to Pre-train Graph Neural Networks(图预训练与微调差异)
【无标题】
知识图谱用于推荐系统问题(MVIN,KERL,CKAN,KRED,GAEAT)
【RS采样】A Gain-Tuning Dynamic Negative Sampler for Recommendation (WWW 2022)
Transformer变体(Routing Transformer,Linformer,Big Bird)
投屏收费背后:爱奇艺季度盈利,优酷急了?
Eureka使用记录
【AI4Code】CodeX:《Evaluating Large Language Models Trained on Code》(OpenAI)
Go 垃圾回收器指南
PHP curl post x-www-form-urlencoded
【GCN-RS】Region or Global? A Principle for Negative Sampling in Graph-based Recommendation (TKDE‘22)
Brpc source code analysis (IV) -- bthread mechanism
OSPF comprehensive experiment
JS interview question: handwriting throttle function