Synchronized

本质是一种悲观锁
CAS: compare  and swap,比较和交换,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做
 
乐观锁与悲观锁 :
独占锁是一种悲观锁,synchronized就是一种独占锁,它假设最坏的情况,并且只有在确保其它线程不会造成干扰的情况下执行,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一个更加有效的锁就是乐观锁。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。
 
 
使用:1.修饰普通方法,锁住的是当前对象
          2.修饰类方法,锁住的是Class对象
          3.修饰块,锁住的是括号中的对象
 
实现原理:在Java SE 1.6以前,Synchronized常被称为重量级锁,之后引入了偏向锁和轻量级锁,对Synchronized进行了改进
        
     Synchronized用的锁存储在对象头中
 
锁的四种状态:无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态,这几个状态会随着竞争情况逐渐升级,锁可以升级但不能降级
 
1.偏向锁:
               大多数情况下,锁不仅存在多线程竞争,而且总是由同一线程获得,为了让线程获得锁的代价变低,引入了偏向锁。
               锁的获得:当一个线程访问同步代码块时,会在对象头和栈帧的锁记录中记录锁偏向的线程ID,以后该线程再进入或退出同步代码块时不需要再进行CAS操作加锁和解锁只需测试一下对象头的markword中是否存有指向当前线程的偏向锁,测试成功,表示线程已获得锁,测试失败,则检查markword中偏向锁的标志是否设为1,如果不是,使用CAS竞争锁,如果是,则尝试用CAS将对象头的偏向锁指向当前线程
               锁的撤销:使用了一种等待竞争出现才释放锁的机制
2.轻量级锁:
               加锁:线程在执行同步块之前,JVM会现在当前线程的栈帧中创建用于存储锁记录的空间,并将对象头的markword复制到空间中,线程尝试使用CAS将对象头的markword替换为指向锁记录的指针,如果成功,则当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁
               解锁:会使用原子的CAS操作将Displaced markword替换回对象头,如果成功,则表示没有竞争发生,如果失败,表示当前锁存在竞争,锁就会膨胀成重量级锁
 
 
Lock
相比Synchronized,需要显示地获取和释放锁,但是却更加灵活
                              能够中断地获取锁,获取到锁的线程能够响应中断,当获取到锁的线程被中断时,抛出中断异常
                              超时获取锁,如果在规定的时间之内没能获取到锁,则返回
posted @ 2016-07-07 10:28  贴地  阅读(720)  评论(0)    收藏  举报