Principle of non-lock class 1.1 CAS
The process of the CAS algorithm is this: it contains 3 parameters CAs (v,e,n). V represents the variable to be updated, E represents the expected value, and n represents the new value. The value of V is set to n only if the V value equals the E value, and if the V and E values are different, the current thread does nothing if the other thread has already updated. Finally, the CAs returns the true value of the current v. CAS operations are carried out in an optimistic manner and always think that they can successfully complete the operation. When multiple threads use CAs to manipulate a variable at the same time, only one wins, and the update succeeds, and the rest fails. Failed threads are not suspended, they are only told to fail, and they are allowed to try again, and of course allow failed threads to abandon the operation. Based on this principle, CAS operations can find other threads interfering with the current thread and handle it appropriately, even without a lock.
1.2 CPU Instructions
Second, the use of lock-free class 2.1 Atomicinteger
Overview
java.util.concurrent.atomicpublic class AtomicInteger extends Number implements java.io.Serializable
Main interface
Public Final int Get()//Get current value Public Final void Set(intNewValue)//Set Current value Public Final int Getandset(intNewValue)//Set new value and return old value Public Final Boolean Compareandset(intExpectintU//If the current value is expect, set to u Public Final int getandincrement()//Current value plus 1, return old value, similar to i++ Public Final int getanddecrement()//Current value minus 1, return old value, similar to i-- Public Final int Getandadd(intDelta//Current value increment delta, return old value Public Final int Incrementandget()//Current value plus 1, return new value, similar to ++i Public Final int Decrementandget()//Current value minus 1, returns the new value, similar to the-I. Public Final int Addandget(intDelta//Current value increment delta, return new value
Implementation of the main interface
// 内部定义了一个value,AtomicInteger只是对它的封装privatevolatileint value;
Compareandset
valueOffset是偏移量
Example
2.2 Unsafe
Overview
非安全的操作,比如:根据偏移量设置值park() 把线程停下来底层的CAS操作非公开API,在不同版本的JDK中,可能有较大差异
Main interface
//Gets an int value on the offset of the given object Public native int getInt(java.Lang.ObjectARG0,LongARG1);//Set int value on a given object like offset Public native void Putint(java.Lang.ObjectARG0,LongArg1,intARG2);//Get the offset of the field in the object Public native Long Objectfieldoffset(Field f);//sets the int value of the given object, using the volatile semantics Public native void Putintvolatile(Object O,LongOffsetintx);//Gets the int value of the given object, using the volatile semantics Public native void Getintvolatile(Object O,LongOffset);//And Putintvolatile (), but it requires that the field being manipulated is a volatile type Public native void Putorderedint(Object O,LongOffsetintx);
2.3 atomicreference
Overview
对引用进行修改是一个模板类,抽象化了数据类型
Main interface
get()set(V)compareAndSet()getAndSet(V)
Example
2.4 atomicstampedreference
Overview
解决ABA问题一个变量初始值为A线程1读取变量 00:00线程2读取变量 00:03线程2将变量修改为B 00:05线程3读取变量 00:06线程3将变量修改为A 00:08线程1根据变量做计算 00:10线程1将变量修改为C 00:12
Main interface
// 比较设置 参数依次为:期望值 写入新值 期望时间戳 新时间戳publicbooleancompareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp)// 获得当前对象引用publicgetReference()// 获得当前时间戳publicintgetStamp()// 设置当前对象引用和时间戳publicvoidsetint newStamp)
Example
Public classAtomicstampedreferencedemo {StaticAtomicstampedreference<integer> Money =NewAtomicstampedreference<integer> ( +,0); Public Static void Main(string[] args) {//Simulate 3 charge threads, balance less than 20 o'clock charge and only charge once for(inti =0; I <3; i++) {Final intTimestamp = money.Getstamp();NewThread () { Public void Run() { while(true) {Integer m = money.getreference();if(M < -) {if(Money.Compareandset(M, M + -, timestamp, timestamp +1)) {System. out.println("The balance is less than 20 yuan, the recharge is successful, the balance:"+ Money.getreference()); } }Else{//Balance greater than 20, no need to recharge Break; } } } }.Start(); }//Simulate a consumer thread NewThread () { Public void Run() {//Consumption 10 times, the balance is more than 10 yuan to spend for(inti =0; I <Ten; i++) { while(true) {intTimestamp = money.Getstamp(); Integer m = money.getreference();if(M >Ten) {if(Money.Compareandset(M, M-Ten, timestamp, timestamp +1)) {System. out.println("Successful consumption of 10 yuan, balance:"+ Money.getreference()); Break; } }Else{System. out.println("Not enough balance."); Break; } }Try{Thread.Sleep( -); }Catch(Interruptedexception e) { } } } }.Start(); }}
2.5 Atomicintegerarray
Overview
支持无锁的数组
Main interface
//Get the elements of the array I subscript Public Final int Get(intI//Get the length of the array Public Final int length()//Set the array I subscript to newvalue and return the old value Public Final int Getandset(intIintNewValue)//CAS operation, if the element i subscript is equal to expect, set to update, set to return True Public Final Boolean Compareandset(intIintExpectintUpdate//Add 1 to the element I subscript Public Final int getandincrement(intI//Reduce the element I subscript by 1 Public Final int getanddecrement(intI//Add a Delta (Delta can be negative) to the element I subscript Public Final int Getandadd(intIintDelta
Example
2.6 Atomicintegerfieldupdater
Overview
让普通变量也享受原子操作
Main interface
// 工厂方法AtomicIntegerFieldUpdater.newUpdater()incrementAndGet()
Description
1. Updater只能修改它可见范围内的变量。因为Updater使用反射得到这个变量。如果变量不可见,就会出错。比如如果score声明为private,就是不可行的。2. 为了确保变量被正确读取,它必须是volatile类型的。如果我们原有代码中未声明这个类型,那么简单声明一个就行,这不会引起什么问题。3. 由于CAS操作会通过对象实例中的偏移量直接进行赋值,因此它不支持static字段(Unsafe.objectFieldOffset()不支持静态变量)
Example
Three, lock-free algorithm 3.1 vector implementation
Add method
Description
数组实现modCount++ 记录被修改的次数ensureCapacityHelper(elementCount+1) 做容量检查
Expansion
3.2 Lock-free vector implementation
Java high concurrency-no lock