在 java 高并发编程, 有几个很重要的内容:
1.CAS 算法
2.CPU 重排序
3. 缓存行伪共享
我们先来说说高并发世界中的主要关键问题是什么?
是数据共享.
因为多线程之间要共享数据, 就会遇到各种问题. 如下图:
如果两个线程同时写入, 那怎么保证数据的一致性? 是线程 1 先写, 还是线程 2 先写, 这是个问题. 那要如何解决这个问题?
答案是: 加锁.
比如, 线程 1 先访问共享数据区, 那么它就先把这块数据区锁起来. 后面如果其他线程要访问这个共享区, 首先要从线程 1 这里获取锁, 才能进一步访问这个共享区. 这里很好理解,
其实相当于这样的情景, 你有一个抽屉, 抽屉有把锁, 这个锁的钥匙, 在你手上, 你就可以打开抽屉, 往里面存放或拿取物件. 其他人, 要从这个抽屉里存放东西, 必须征得你的同意, 从你手上拿到钥匙, 然后, 他才能用这把钥匙打开抽屉, 进行存放物件的动作. 如下图:
回到高并发的线程世界, 我们知道, 可以用加锁来解决多线程访问共享数据区的问题. 那问题又来了, 那这把锁, 先交给谁呢? 怎么解决这个问题呢?
答案是: 锁竞争.
多线程, 如果在优先级一样的情况下, 大家进行公平竞争? 那怎么样才算公平竞争呢? 一般情况下, 我们都可以想到: 先到先得.
是的, 一般情况下, 操作系统对线程竞争, 都取用这个方式, 这样也符合常理.
好, 线程 1 来了, 获得一把锁, 对这个共享数据区进行锁定访问. 那别的线程, 只能等待这个线程 "办完事" 后, 释放锁. 这时, 这些别的线程就进入等待状态.
现在问题, 又来了, 如果线程 1 只是对这个共享数据区进行读访问, 是否有必要把这个数据区全面锁, 不让其他线程进行读访问呢?
没有必要!
怎么解决?
读写分离!
分别定义两把锁, 一把读锁, 一把写锁. 写锁, 还是对写有独占权. 读锁, 就可以无限量地分发给其他多个线程. 这样不影响共享数据区的数据一致性.
其实, 读写分离, 是架构设计和数据库设计中一个很重要的设计思想, 也是高性能的一种设计理念.
好了, 今天, 我们主要讲多线程高并发编程的核心概念: 线程锁.
明天, 我们继续讲锁的底层实现原理.
来源: https://www.cnblogs.com/gyc567/p/11014782.html