并发编程的三个性质
- 原子性:一个操作或多个操作要么全部执行完成且执行过程不被中断,要么就不执行。
- 可见性:当多个线程同时访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
- 有序性:程序执行的顺序按照代码的先后顺序执行。
公平锁与非公平锁
- 公平锁就是FIFO
- 非公平锁不是FIFO,会直接请求资源
- 非公平锁性能会比公平锁高很多,因为减少了上下文切换时间
-
synchronized一定是非公平锁 -
ReentrantLock默认是非公平锁,也可以是初始化为公平锁
悲观锁与乐观锁
- 悲观锁拿数据会上锁
- 乐观锁拿数据不会上锁,但是会判断数据是否被别的线程修改了
-
synchronized和ReentrantLock都是悲观锁 - 数据库锁也是悲观锁
- CAS(compare and swap) 是乐观锁
- 并发编程中乐观锁比较适用于竞争不激烈的资源
synchronized 与 lock的区别
https://blog.csdn.net/u012403290/article/details/64910926
volatile 关键字
- 每次使用变量时都要从主内存读取
- 禁止指令重排序
- 可以保证可见性和有序性,不能保证原子性
ConcurrentHashMap底层实现
-
ConcurrentHashMap是线程安全的(废话) - JDK1.7之前是segment锁,即把entry分成很多段,对段上锁
- JDK1.8只对entry上锁,采用CAS+
synchronized的策略,当entry为空时用CAS
Hashtable底层实现
-
Hashtable是线程安全的,它的方法都有synchronized修饰 - 普通的
HashMap不是线程安全的 - 只有一把锁锁整个表,效率非常低,实际基本不用