![](https://img-blog.csdnimg.cn/88e4ce9b47554c72a5cc286ee9d953a6.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224)
JUC并发编程
JUC 并发编程相关的知识
一切随缘~~~
最难不过坚持。
展开
-
双重检测锁中的单例对象,为什么要使用 Volatile 修饰?
在还没有执行完第三步之前,又来了一个线程,这时候 instance!= null,于是就拿到了一个没有初始化的空对象,就出现了问题。● 第三步:将instance 指向对象的内存地址,将内存地址赋值给instance。如果第二步和第三步,发生了指令重排序,先执行第三步,再执行第二步。双重检测锁中的单例对象,为什么要使用 Volatile 修饰?保证 instance 变量的可见性,同时可以禁止指令重排序。new 一个对象,在JVM层面是 3 条指令。● 第二步:对对象进行初始化操作。原创 2023-10-20 17:42:46 · 127 阅读 · 0 评论 -
Volatile 是怎么保证可见性的?谈谈Volatile的可见性
谈到Volatile的可见性,就得先谈谈 Java内存模型。每个线程都有自己的工作内存,数据都是先从主存中,拉取到工作内存中,操作完数据之后,再把数据推送回主存中的。被Volatile修饰的变量,被修改之后,会立刻通过总线,将最新值推送回主存中,还会通过总线通知其他线程,你们工作内存中的数据失效了,要到主存中去拉取最新值。底层原理:对于Volatile 修饰的变量,在汇编层面,会在写操作的前面,加上 lock 指令。● 2.由于总线的嗅探技术,对于lock前缀的嗅探,会导致其他cpu核心的缓存失效。原创 2023-10-20 17:41:48 · 132 阅读 · 0 评论 -
Volatile 可以保证什么特性?有什么作用?
cpu 都是把数据从内存拉取到自己的缓存中进行运算,然后在写回内存的。每个cpu 核心都有自己独立的缓存。所以就造成了,多核并发的场景下,数据可能被 A 线程修改了,但是其他线程不知道,cpu 核心还在使用缓存中旧的数据。可以保证可见性,有序性,禁止指令重排序。但是不能保证原子性。线程上下文切换的时候,还是有可能出现线程安全问题。Volatile 就是来解决这个缓存一致性问题的。Volatile 可以保证什么特性?有序性,就是所谓的禁止指令重排序。原创 2023-10-20 17:41:16 · 125 阅读 · 0 评论 -
CAS 产生的 ABA 问题是什么?怎么解决?
CAS操作可能会出现ABA问题,所谓ABA问题是指在执行CAS操作时,由于CAS操作只对值进行比较,不考虑值的版本等其它附加信息,因此可能导致某个线程误认为成功地将值从A修改为B,但实际上另一个线程已经将值从B又修改回了A,这样就会导致该线程认为修改成功,但实际上数据已经被修改了两次,出现了不一致的情况。CAS 产生的 ABA 问题是什么?原创 2023-10-20 17:40:45 · 464 阅读 · 0 评论 -
CAS 是什么?
更新值之前,会先判断跟预期值一不一样,如果不一样则不更新,这里会有重试机制;如果跟预期值一样,则更新。这里会产生 ABA问题。CAS 一般结合 Volatile,来一起使用。Volatile,来保证能拿到变量的最新值。CAS 是硬件层面,CPU提供的原子指令。由于该指令在硬件层面实现,因此效率非常高。Compare And Swap,无锁编程。原创 2023-10-20 17:40:07 · 56 阅读 · 0 评论 -
谈谈悲观锁
像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行重试,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。悲观锁就是比较悲观,认为自己使用数据的时候,一定会有其他线程来修改数据,所以在获取数据的时候,会先加锁,确保数据不会被其他线程修改。乐观锁,悲观锁,并不是特指什么具体的锁,而是一种策略,思想。● Lock 接口的实现类,比如 ReentrantLock。● Synchronized 关键字。原创 2023-10-19 18:14:38 · 104 阅读 · 0 评论 -
谈谈乐观锁
像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的整个吞吐量。乐观锁,只是在更新数据之前,看一下数据有没有被别的线程修改过,如果没有数据没有被别的线程修改过,也不能说的这么绝对,因为存在ABA的问题,就更新数据;如果数据被别的线程修改过了,就不更新,进行重试。乐观锁就是比较乐观,认为自己在使用数据的时候, 不会有其他线程对其进行修改,所以就不会加锁,说白了乐观锁,根本没有锁,是一种无锁编程。乐观锁,悲观锁,并不是特指什么具体的锁,而是一种策略,思想。原创 2023-10-19 18:14:04 · 104 阅读 · 0 评论 -
Java 对象是什么样子的?
是因为,Java 对象头中存储了 Class 对象的指针。Java 这样设计的好处,可以节省内存的占用,类的元信息有一份就行了,new 出来的对象,可以复用这一份。其实不然,Java 对象中其实只存储了数据,并没有存储其他属性信息。● Object Body,具体的属性值,基本数据类型,就存储值;● Mark Word,32位,64位Java虚拟机,分别是 32 位,64 位。这里的 s 变量,就是我们常说的引用,这里是强引用。指向对象中的 Java对象。Java对象的具体组成:对象头 + 对象体。原创 2023-10-19 18:11:42 · 162 阅读 · 0 评论 -
说说对 JVM 内存模型的理解
【缓存的命中率是很高的】CPU读写的时候,只操作缓存里的数据,计算完了之后,再把数据写回到内存中。● Java内存模型可不是一个物理上的结构,内存条中可没有什么主内存,工作内存什么的。它只是JVM制定出来的一套规范,Java内存模型,就是对CPU,寄存器,三级缓存,内存,做的一个封装,一个抽象。○ 子线程不能直接使用主内存中的数据,需要先拷贝一份到自己的工作内存中。● 现在的CPU都是多核的,那么缓存就有多个,A 缓存里面的数据被修改了,但是其他缓存并不知道,这时候这会出现数据不一致的问题。原创 2023-10-19 18:07:42 · 95 阅读 · 0 评论 -
Synchronized 锁升级过程
Synchronized 锁升级过程原创 2023-10-16 21:53:50 · 213 阅读 · 0 评论 -
深入理解 Synchronized
深入理解Synchronized,以及锁升级的过程原创 2023-01-06 20:39:27 · 455 阅读 · 0 评论 -
自己手写一个简易版本的线程池【Java】【详细注解,含思考过程和知识点】
【代码】自己手写一个简易版本的线程池【Java】【详细注解,含思考过程和知识点】原创 2022-12-29 20:44:21 · 282 阅读 · 0 评论 -
自己手写一个简易版本的数据库连接池【Java】【详细的注解,有思考过程和知识点】
【代码】自己手写一个简易版本的数据库连接池【Java】【详细的注解,有思考过程和知识点】原创 2022-12-28 20:55:51 · 429 阅读 · 0 评论 -
Double-Checked-Locking,双重检测,单例模式
double checked locking 双重检测锁,单例模式原创 2022-12-25 21:58:16 · 102 阅读 · 0 评论 -
优雅的写出线程t1, t2, t3分别交替输出5次 a, b, c。三种写法,a.wait¬ify b.await&signal c.park&unpark
线程t1, t2, t3分别交替输出 a, b, c => 最终输出 abcabcabcabcabc原创 2022-12-24 21:00:08 · 88 阅读 · 0 评论 -
设计模式之生产者,消费者,使用了保护性暂停【wait,notify】
设计模式之生产者,消费者原创 2022-12-24 12:46:00 · 103 阅读 · 1 评论 -
优雅的中止线程:两阶段中止模式
优雅的中止线程原创 2022-12-23 15:19:13 · 110 阅读 · 0 评论