一些名词解析
互斥同步:一个共享资源在一段时间内只有一个线程共享(1v1)(悲观策略,认为只要不占有这个共享资源,就会出问题)
非阻塞同步:先操作,如何没有其他线程争用共享资源,操作成功;出现竞争那再进行补偿措施。(乐观)
公平锁:先来先得
非公平:来的早不如来的巧
synchronized关键字
关键词:实现互斥同步、悲观锁、非公平锁
synchronized实现同步的基础:java中的每个对象都有一个内部锁。内部锁来管理试图进入synchronize方法的线程。
public synchronized void method(){
method body
}
等价于
public void method(){
this.intrinsicLock.looc();try{
method body
}
finally{this.intrinsicLock.unlock();
}
-
对象内部锁及其优化
如上图所示,对象里面有个对象头Mark Word,数据信息如表所示。
可以看到为了优化这个对象内部锁,这个锁有四个状态,无锁,偏凉锁、轻度级锁、重量级锁。锁会不断升级但不能降级(可以释放锁变回无锁状态)。
偏向锁:
轻度级锁:
-
重入
避免我锁我自己的情况,一个线程每次再获取这个锁(自己持有的)的时候,锁的获取计数值就会+1,示退出同步代码块-1,为0时释放。(线程要请求其他线程持有的锁,那就阻塞)
Lock接口
关键词:显示锁
public interface Lock{
void lock();//加锁
void lockInterruptibly() throws InterruptedException;//中断锁
boolean tryLock();//轮转锁
boolean tryLock(long timeout,TimeUnit unit) throws InterruptedException;//定时锁
void unlock();//解锁
Condition newCondition();//内置条件队列
}
ReentrantLock(一种Lock接口的实现)
关键词:互斥同步、显示锁、重入锁
看lock接口可知道,ReentrantLock这个实现了Lock接口的类一定可以等待中断、轮转定时,能绑定都多个Condition对象、实现公平锁
注:使用时要在finally里释放锁。
ReentrantReadWriteLock(读写锁)
关键词:读共享、写互斥;
里面包含new 一个读写锁对象后,包含readLock()读锁,和writeLock()写锁两种,可以对所有读的方法加读锁,所有写的方法加写锁。
volatile 变量
主要作用::用来确保将变量的更新操作通知给其他线程,即所有线性,任意时刻读到的都是最新的准确的.(要是非volatile变量的64为变量,是会成2次分32位的操作,所以可能会读到A线程新写入的高32位,和B线程新写入的低32位.)
两个特性:
- 1 保证变量对所有线程的可见性(一个线程修改了它,其他线程是立刻知道的)
- 2 禁止指令重排优化(比如修改一个volatile变量的时候,修改前的java代码处理器都要执行完(不管直接是否有依赖)之后,才会执行volatile变量的代码)
特性的实现
一个volatile变量的代码变成汇编代码的时候,会比其他的多一行代码
lock addl $0x0,(%esp)
- 1 带这个lock前缀的指令会锁缓存,本处理器缓存写入内存,会无效化其他处理器的缓存.这就是特性一的实现
- 2 这个执行形成了内存屏障,在他之前的代码都必须执行完才能执行这条.