最近在做项目的时候遇到了较多的同步问题 。

JAVA 给我们提供了很方便的方法去解决多线程同步的问题   synchronized 关键字  

一直很疑惑  synchronized 是怎么来做同步的呢   实现 原理是什么呢     ?


1 synchronized -- 对象加锁

 所有对象都自动含有单一的锁,JVM负责跟踪对象被加锁的次数。

如果一个对象被解锁,其计数变为0。

在任务(线程)第一次给对象加锁的时候, 计数变为1。

每当这个相同的任务(线程)在此对象上获得锁时,计数会递增。

 只有首先获得锁的任务(线程)才能继续获取该对象上的多个锁。

每当任务离开时,计数递减,当计数为0的时候,锁被完全释放。

synchronized就是基于这个原理,同时synchronized靠某个对象的单一锁技术的次数来判断是否被锁,所以无需(也不能)人工干预锁的获取和释放。

 原理!!!!!!!!!! 如果结合方法调用时的栈和框架(如果对方法的调用过程不熟悉建议看看http://wupuyuan.iteye.com/blog/1157548),

 不难推测出synchronized原理是基于栈中的某对象来控制一个框架,

所以对于synchronized有常用的优化是锁对象不锁方法。

实际上 synchronized作用于方法时,锁住的是“this”,

作用于静态方法/属性时,锁住的是存在于永久带的CLASS,相当于这个CLASS的全局 锁,锁作用于一般对象时,锁住的是对应代码块。

在HotSpot中JVM实现中,锁有个专门的名字:对象监视器。   

 当多个线程同时请求某个对象监视器时,对象监视器会设置几种状态用来区分请求的线程 Contention List:所有请求锁的线程将被首先放置到该竞争队列,是个虚拟队列,不是实际的Queue的数据结构。  Entry List:EntryList与ContentionList逻辑上同属等待队列,ContentionList会被线程并发访问,为了降低对 ContentionList队尾的争用,而建立EntryList。,Contention List中那些有资格成为候选人的线程被移到Entry List  Wait Set:那些调用wait方法被阻塞的线程被放置到Wait Set  OnDeck:任何时刻最多只能有一个线程正在竞争锁,该线程称为OnDeck