Java
232 篇笔记
- 6.1 先谈硬件historical
要理解JMM,我们先要理解底层硬件的工作原理 1. 冯诺依曼体系结构 冯诺依曼提出将程序当作数据对待,将程序(指令)和数据用同样的方式储存。根据这个理论计算机被分成控制器、运算器、存储器、输出设备、输入设备这几个部件,如下图 其中运算器和控制器组合成了CPU,CPU执行指令或者操作数据的时候都要跟存
- 6.2 2.Synchronizedhistorical
1. 是什么 Java 中悲观锁的一种实现,相比于 volatile 是重量级锁,可以保证原子性、有序性、可见性 - 重量级 会引起上下文切换(会造成线程阻塞) - 原子性 synchronized 方法、synchronized 代码块被视作原子的 - 有序性 线程 A 对于锁 X 的释放发生于线
- 6.3 3.volatilehistorical
1. 是什么 Java 的轻量级锁,主要保证了有序性、可见性和一定的原子性 - 轻量级 相比于 synchronized,volatile 不会引起上下文切换(不会造成线程阻塞) - 原子性 对任意单个 volatile 变量的读/写具有原子性,但类似于 volatile++这种复合操作不具有原子性
- 6.4 4.CAShistorical
1. 是什么 要理解CAS,我们首先得了解乐观锁和悲观锁的概念。 1.1. 乐观锁与悲观锁 悲观锁:假设每次操作数据的时候总有人一起操作数据。因此我操作数据前先上锁,直到我操作完释放锁,别人都只能阻塞等待。 乐观锁:假设每次操作数据的时候没人跟我一起操作数据。因此我只在更新的时候检查一下有没有其他人
- 6.5 5.AQShistorical
1. 是什么 队列同步器,用于实现JUC包的其他并发工具类 2. 如何使用 一般我们不直接使用AQS,而是使用JUC中的其他工具类(如CountDownLatch等),这些工具类覆盖了几乎所有的使用场景,只有在这些工具类无法满足我们的需求时,才去用AQS实现自己的并发工具。 实现的一般的套路如下:
- 6.6 6.ReentrantLockhistorical
1. 是什么 在jdk5之前,synchronized效率极低,于是写了ReentranLock代替。 后来jdk7优化了synchronized,参考锁的优化.md。两者性能区别不大 1.1. synchronized vs ReentranLock 比较 Synchronized Reentra
- 6.7 7.Lock之Conditionhistorical
1. 是什么 类似object的wait和notify方法配合synchronized使用 condition的await和notify方法配合Lock使用,用来实现条件等待与唤醒 2. 如何使用 - 生产者消费者模式 3. 实现原理 3.1. uml 3.2. 创建Condition对象 - ne
- 6.8 8.CyclicBarrierhistorical
1. 是什么 可重复使用的计数器,让一堆线程互相等待,条件满足时一起往下执行 底层使用Lock+Condition实现阻塞等待和唤醒 2. 如何使用 2.1. 不带Runnable 当所有线程都到达await点的时候才一起往下执行 2.2. 带Runnale 当所有线程都到达await点的时候,最后
- 6.9 9.CountDownLatchhistorical
1. 是什么 不能重复使用的计数器。让一个线程等待其他线程完事再往下执行,类似于Thread.join() 底层使用AQS实现 2. 如何使用 - 注意 这里countdown的线程不会互相等待,谁先执行完谁就先退出 2.1. CountDownLatch VS CyclicBarrier Coun
- 6.10 10.CopyOnWriteArrayListhistorical
1. 是什么 这个list借鉴的是读写分离的思想(弱一致性) - 读的时候可以并发读,不加锁; - 写的时候需要加锁,复制一份原有数据进行修改,改完后写回list 2. 如何使用 3. 原理 3.1. 构造方法 - 可以看到底层是通过object数组实现, - 通过 getArray/setArra