锁的相关概念:
锁消除:比如StringBuffer 是线程安全的,里面的方法是带synchronized,在没有竞态条件的情况下,在真正执行的过程中JIT做了优化,把锁消除掉了。
锁粗化:锁的范围扩大。
偏向锁:避免每个对象都创建ObjectMonitor浪费资源,提出了偏向锁
轻量锁(自旋锁),重量锁(监视器锁)
自旋锁:为了不放弃CPU执行事件,循环的使用CAS技术对数据尝试进行更新,直至成功。
锁升级(锁膨胀):从 无锁->偏向锁(减少在无竞争的情况下,JVM资源的消耗)出现两个及以上线程竞争->轻量锁(CAS修改状态)线程CAS自旋一定次数后之后,升级->重量锁(对象的mark word内部会保存一个监视器锁的地址) 的过程,锁逐渐的升级
对象的mark word里面会包含四种状态: 00:轻量锁 01:无锁 10:重量锁 11:可以被GC
悲观锁:假定会发生并发冲突,同步所有对数据的相关操作,从读数据开始上锁。
乐观锁:假定没有冲突,在修改数据时如果发现数据和之前获取的不一致,则读取最新数据,修改后重试修改。
公平锁,非公平锁:争抢锁的顺序,如果是按先来后到,则为公平。
可重入锁,不可重入锁:线程拿到一把锁后,可以自由的进入同一把锁所同步的其他代码。
独享锁:给资源加上写锁,线程可以修改资源,其他线程不能再加锁;(单写)
共享锁:给资源加上读锁后只能读不能改,其他线程也只能加读锁,不能加写锁;(多读)
synchronized 属于悲观锁,独享锁,可重入锁,基于对象监视器实现
synchronized 关键字可以修饰代码块,可以修饰方法
修饰.class,或者放在静态方法上面时,属于类锁。
修饰对象,或者修饰普通方法属于实例锁。
属于最基本的线程通信机制,基于对象的监视器实现。
JAVA中每个对象都与一个监视器相关联,一个线程可以锁定或解锁。一次只有一个线程可以锁定监视器。
试图锁定该监视器的任何其他线程都会被阻塞,直到它们可以获得该监视器上的锁定为止。