在多
线
程并
发编
程中
synchronized
一直是元老
级
角色,很多人都会称呼它
为
重量
级锁
。但
是,随着
Java SE 1.6
对
synchronized
进
行了各种
优
化之后,有些情况下它就并不那么重了。
先来看下利用
synchronized
实现
同步的基
础
:
Java
中的每一个
对
象都可以作
为锁
。具体表
现
为
以下
3
种形式。
·
对
于普通同步方法,
锁
是当前
实
例
对
象。
·
对
于静
态
同步方法,
锁
是当前
类
的
Class
对
象。
·
对
于同步方法
块
,
锁
是
Synchonized
括号里配置的
对
象。
{
//TODO
了解管程 ( )
每一个对象和类都与一个监视器相关联
要线程独占某块数据/代码(SpecialRoom) ,那么先进入Hallway等待,然后调度器基于某些规则(如先进先出)从Hallway中取一个线程,若线程处于被挂起状态 那么就把它送进等待房间,过一段时间再送进 SpecialRoom。
而Monitor (监视器)的作用就是
保证 仅一个线程访问受保护的数据/代码
在Java中 每个对象和类都有一个监视器与之关联。为了实现监视器的互斥功能,锁(有时候也称为互斥体)与每一个对象和类关联。在操作系统书中,这叫做信号量,互斥锁也被称为二元信号量。
如果一个线程拥有某些数据上的锁,其他线程想要获得锁只能等到这个线程释放锁。如果我们在进行多线程编程时总是需要编写一个信号量,那就不太方便了。幸运的是,我们不需要这样做,因为JVM会自动为我们做这件事。
JVM会实现一个信号量,来与每个类/对象的监视器关联。
为了声明一个同步区域(这里意味着数据不可能被超过一个线程访问),Java提供了synchronized块和synchronized方法。一旦代码被synchronized关键字绑定,它就是一个监视器区域。它的锁将会在后面被JVM实现。
}
来实现
方法同步和代
码块
同步,但两者的
实现细节
不一
样
。代
码块
同步是使用
monitorenter
和
monitorexit
指令
实现
的,而方法同步是使用另外一种方式
实现
的,
细节
在
JVM
规
范里并没有
详细说
明。但是,方法的同步同
样
可以使用
这
两个指令来
实现
。
monitorenter
指令是在
编译
后插入到同步代
码块
的开始位置,而
monitorexit
是插入到方法
结
束处和异常处
,
JVM
要保
证