当前位置:网站首页>Deep understanding of JUC concurrency (IX) deep understanding of CAS
Deep understanding of JUC concurrency (IX) deep understanding of CAS
2022-07-20 16:06:00 【I think starfish_ ninety-eight】
List of articles
In depth understanding of CAS
What is? CAS
Compare and exchange : Compare the current Values in working memory and The value in main memory , If this value is expected , Then perform the operation ! If not, keep cycling , Using a spin lock
public class casDemo {
//CAS : CompareAndSet Compare and exchange
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
//boolean compareAndSet(int expect, int update)
// Expectations 、 Update value
// If the actual value and My expectations are the same , Then update
// If the actual value and My expectations are different , Then don't update
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
// Because the expectation is 2020 The actual value becomes 2021 So it will fail to modify
//CAS yes CPU The concurrent primitives of
atomicInteger.getAndIncrement(); //++ operation
System.out.println(atomicInteger.compareAndSet(2020, 2021));// This place uses a spin lock !
System.out.println(atomicInteger.get());
}
}
shortcoming
- The loop takes time
- Only the atomicity of one shared variable can be guaranteed at one time
- It will exist ABA problem
Atomic reference
solve ABA problem ~
ABA problem
If another thread modifies the value, assume that it turns out to be A, Change it to B, And then change it back to A. Of the current thread CAS The operation cannot distinguish the current V Whether the value has changed .
public class casDemo {
//CAS : compareAndSet Compare and exchange
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(2020);
// Change the past and then change it back , Cause deception
System.out.println(atomicInteger.compareAndSet(2020, 2021));
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(2021, 2020));
System.out.println(atomicInteger.get());
//ABA problem , Output true, Cause mistakes
System.out.println(atomicInteger.compareAndSet(2020, 6666));
System.out.println(atomicInteger.get());
}
}
Optimism lock
Atomic operations with version numbers : Use version number , To control the update of data , To avoid “ cheating ”~
package com.marchsoft.lockdemo;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;
/** * Description: * * @author jiaoqianjin * Date: 2020/8/12 22:07 **/
public class CASDemo {
/**AtomicStampedReference Be careful , If a generic is a wrapper class , Pay attention to the reference of objects * Normal operation in business , It's all about objects */
static AtomicStampedReference<Integer> atomicStampedReference = new
AtomicStampedReference<>(1, 1);
// CAS compareAndSet : Compare and exchange !
public static void main(String[] args) {
new Thread(() -> {
int stamp = atomicStampedReference.getStamp(); // Get version number
System.out.println("a1=>" + stamp);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// When modifying operations , The version number is updated for the first time + 1
atomicStampedReference.compareAndSet(1, 2,
atomicStampedReference.getStamp(),
atomicStampedReference.getStamp() + 1);
System.out.println("a2=>" + atomicStampedReference.getStamp());
// Change the value back , The version number is updated again + 1
System.out.println(atomicStampedReference.compareAndSet(2, 1,
atomicStampedReference.getStamp(),
atomicStampedReference.getStamp() + 1));
System.out.println("a3=>" + atomicStampedReference.getStamp());
}, "a").start();
new Thread(() -> {
int stamp = atomicStampedReference.getStamp(); // Get version number
System.out.println("b1=>" + stamp);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Because of the control of version number , So the output here is false, Will not cause deception
System.out.println(atomicStampedReference.compareAndSet(1, 3,
stamp, stamp + 1));
System.out.println("b2=>" + atomicStampedReference.getStamp());
}, "b").start();
}
}
Explanation of other locks
Fair lock / Not fair lock
Fair lock : Multiple threads acquire locks in the order of applying for locks , The thread goes directly into the queue to queue , Always be the first in the queue to get the lock
- advantage : All threads have access to resources , Don't starve to death in the queue
- shortcoming : Throughput will drop a lot , Except for the first thread in the queue , Other threads will block ,cpu The cost of waking up blocked threads can be very high
Not fair lock : When multiple threads get locks , Will directly try to get , If you can't get it, go into the waiting queue , If you can get it, you can get the lock directly
- advantage : Can reduce the CPU Wake up thread overhead , The overall throughput efficiency will be high ,CPU You don't have to wake up all threads , It reduces the number of threads that evoke
- shortcoming : You may also find that , This may result in the thread in the middle of the queue unable to obtain the lock or cannot obtain the lock for a long time , Leading to starvation
Reentrant lock
The house has a gate and an inner gate , You took The key to the gate , It's automatic The key to the inner door
synchronized
public class Demo01 {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread(()->{
phone.sms();
},"A").start();
new Thread(()->{
phone.sms();
},"B").start();
}
}
class Phone{
public synchronized void sms(){
System.out.println(Thread.currentThread().getName()+"=> sms");
call();// There is also a lock here
}
public synchronized void call(){
System.out.println(Thread.currentThread().getName()+"=> call");
}
}
lock
//lock
public class Demo02 {
public static void main(String[] args) {
Phone2 phone = new Phone2();
new Thread(()->{
phone.sms();
},"A").start();
new Thread(()->{
phone.sms();
},"B").start();
}
}
class Phone2{
Lock lock=new ReentrantLock();
public void sms(){
lock.lock(); // details : These are two locks , Two keys
//lock Locks must be paired , Otherwise it will be locked in
try {
System.out.println(Thread.currentThread().getName()+"=> sms");
call();// There is also a lock here
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void call(){
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "=> call");
}catch (Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
}
}
Be careful :
- lock Locks must be paired , amount to lock and unlock The quantity must be the same
- Lock on the outside , You can also unlock it inside ; The lock added inside , It can also be unlocked outside ~
spinlocks
do-while loop , Spin
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
Anatomic design
public class SpinlockDemo {
// Default
// int 0
//thread null
AtomicReference<Thread> atomicReference=new AtomicReference<>();
// Lock
public void myLock(){
Thread thread = Thread.currentThread();
System.out.println(thread.getName()+"===> mylock");
// spinlocks
while (!atomicReference.compareAndSet(null,thread)){
System.out.println(Thread.currentThread().getName()+" ==> Spinning ~");
}
}
// Unlock
public void myUnlock(){
Thread thread=Thread.currentThread();
System.out.println(thread.getName()+"===> myUnlock");
atomicReference.compareAndSet(thread,null);
}
}
class TestSpinLock {
public static void main(String[] args) throws InterruptedException {
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
reentrantLock.unlock();
// Use CAS Spin lock
SpinlockDemo spinlockDemo=new SpinlockDemo();
new Thread(()->{
spinlockDemo.myLock();
try {
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
e.printStackTrace();
} finally {
spinlockDemo.myUnlock();
}
},"t1").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
spinlockDemo.myLock();
try {
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
e.printStackTrace();
} finally {
spinlockDemo.myUnlock();
}
},"t2").start();
}
}
Deadlock
While holding the lock , Try to get the other party's lock
package com.ogj.lock;
import java.util.concurrent.TimeUnit;
public class DeadLock {
public static void main(String[] args) {
String lockA= "lockA";
String lockB= "lockB";
new Thread(new MyThread(lockA,lockB),"t1").start();
new Thread(new MyThread(lockB,lockA),"t2").start();
}
}
class MyThread implements Runnable{
private String lockA;
private String lockB;
public MyThread(String lockA, String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run() {
synchronized (lockA){
System.out.println(Thread.currentThread().getName()+" lock"+lockA+"===>get"+lockB);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB){
System.out.println(Thread.currentThread().getName()+" lock"+lockB+"===>get"+lockA);
}
}
}
}
solve
Mainly for troubleshooting , Solve code problems after troubleshooting
Use
jps
Locate the process number , Find our processjps -l
Use
jstack Process number
, Deadlock information found
边栏推荐
- DS(ArrayStructure)
- 【ARM】新唐NUC977移植WK2124驱动
- PHP anonymous function usage
- 【MATLAB项目实战】基于感兴趣区域的无人机图像压缩技术研究
- 【深度】新派LaaS协议Elephant:重振DeFi赛道发展的关键
- 2022最新String面试题及答案
- vim中单词操作方法总结
- C language simulation to realize character function and memory function
- [depth] the new LAAS agreement elephant: the key to revitalizing the development of the defi track
- Fiddler设置断点(一)
猜你喜欢
MySQL八股文,备战金九银十
深入了解JUC並發(八)線程池
获取疫情资讯数据
Study notes - C string delete character
[development of large e-commerce projects] cache - distributed lock - cache consistency solution -45
NFT市场格局仍未变化,Okaleido能否掀起新一轮波澜?
Obtain epidemic information and data
2022 Henan League game 2: Henan University of Technology
Linux 编译安装redis 离线
浅拷贝和深拷贝的区别?
随机推荐
uniapp通过addInterceptor拦截路由跳转,控制页面是否需要登录
2022 latest algorithm analysis and handwritten code interview analysis
mysql中update和select结合使用
kubeadm介绍
还不懂MySQL数据库?阿里p8架构师带你深入浅出MySQL与优化
NFT市场格局仍未变化,Okaleido能否掀起新一轮波澜?
MySQL将查询的结果作为update更新的数据,且在原字段数据后 CONCAT拼接(lej)
京津冀综合科技服务平台的建设与思考
Pytorch, used by the nonzero instance
Immediate assertion and concurrent assertion in SystemVerilog
2022 latest string interview questions and answers
查询效率提升10倍!3种优化方案,帮你解决MySQL深分页问题
面试官问:如何防超卖,有几种实现方式
微信小程序获取----onenet的数据并控制stm32的板载LED
Obtain epidemic information and data
Enter the first general codeless development platform - IVX
运营商的时代之旅:种下5.5G的魔豆,攀上数字化的天空花园
数据中台、商业智能BI业务访谈(一):行业和业务研究的准备
参与开源社区还有证书拿?
PG Database install Timescale Database and Backup configuration