什么是原子操作?如何实现原子操作
Atom(不可分割)
syn基于阻塞的锁的机制,1.被阻塞的县城优先级很高。2. 拿到锁的线程一直不释放锁。3.大量的竞争,消耗CPU,同时带来死锁或者其他安全问题。
CAS原理
CAS(Compare And Swap),指令级别保证是一个原子操作。
三个运算符:一个内存地址v,一个期望的值A,一个新值B。
基本思路:如果地址v上的值和期望的值A相等,就给地址v赋给新值B,如果不是,不做任何操作。
循环(死循环,自旋)里不断的进行CAS操作。
利用了现代处理器都支持的CAS的指令,循环这个指令,直到成功为止。
CAS的问题
ABA问题:引入版本号
开销问题:CAS长期操作不成功,cpu不断地循环
只能保证一个共享变量的原子操作
JDK中相关原子操作类的使用
更新基本类型类
更新基本数组类
更新引用类型
AtomicMarkableReference,boolean 有没有动过
AtomicStampedReference,动过几次
原子更新字段类
显示锁
Lock接口和核心方法
使用显示锁的范式
private Lock lock = new ReentrantLock();
private int count;
public void increament(){
lock.lock();
try{
count++;
}finally{
lock.unlock();
}
}
Lock接口和synchronized的比较
synchronized代码简洁。Lock:业务需要获取锁可以被中断,超时获取锁,尝试获取锁.
可重入锁ReentrantLock、所谓锁的公平和非公平
如果在时间上,先对锁进行获取的请求,一定先被满足,这个锁就是公平的,不满足就是非公平
非公平锁的效率一般来讲更高,
ReadWriteLock接口和读写锁ReentrantReadWriteLock,什么情况下用读写锁?
ReentrantLock和synchronized关键字,都是排他锁(同一时刻只允许一个线程访问)。
读写锁:同一时刻允许多个读线程同时访问,但是写线程访问的时候,所有的读和写都被阻塞。 最适宜读多写少的情况
Condition
Lock和Condition实现等待通知
signal() 唤醒 await()等待
private Lock lock = new ReentrantLock();
private Condition cond1 = lock.newCondition();
private Condition cond2 = lock.newCondition();
一个lock可以对应多个condition
了解LockSupport工具
作用
阻塞了一个线程
唤醒了一个线程
构建同步组件的基础工具
park开头的方法
阻塞
unpark(Thread thread)方法
唤醒