标签:监视器 避免 而在 互斥 lock java对象 技术 来讲 通过
synchronized是Java中的关键字,在并发编程中被称为内置锁或者监视器锁。当用它来修饰一个方法或者一个代码块的时候能够保证同一时刻最多只有一个线程执行该段代码。
Java的内置锁相当于一种互斥锁,最多只有一个线程能够持有这种锁,故而由这个锁保护的同步代码块会以原子方式执行,多个线程在执行该代码时就不会相互干扰。
但由于被锁保护的同步块代码是以串行形式来访问的,即多个线程以独占的方式访问对象,而这也导致如果被锁保护的同步代码块的作用范围过大,会导致并发不良。
这里有必要简单讲一下内置锁的实现同步的原理:Java中的每一个对象都可以作为锁,synchronized用的锁其实存在Java对象头里(这也是为什么称其为内置锁的原因)。
而根据synchronized修饰的方法或方法块的不同,其锁的形式也不一。
以下是一个简单的例子,表示synchronized会根据其修饰对象不同而获取不同的锁。
public class Test { /** * 修饰方法,会对该类的实例进行加锁,该实例的所有synchronized方法都必须 * 等待当前锁释放后才能访问 */ public synchronized void syn1(){ //TODO } /** * 同步静态方法,会对类对象上锁,该类的其他实例的synchronized方法必须等当前锁释放后才能访问 */ public synchronized static void syn3() { //TODO } /** * 同步指定对象,会对对象上锁,其他使用该对象的synchronized方法必须等当前锁释放后才能访问 */ public void syn4() {
//obj仅代表要修饰的具体对象名 synchronized (obj) { } } /** * 同步指定的类,会对类对象上锁,该类的其他实例的synchronized方法必须等当前锁释放后才能访问 */ public void syn5() {
//ClassName仅代表要修饰的具体类 synchronized(ClassName.class) { //TODO } } }
此外,实现同步是要很大的系统开销作为代价的,甚至可能造成死锁(锁嵌套时),所以尽量避免无谓的同步控制。此外,为了并发的性能考虑,在实际使用synchronized关键字时,要注意确定synchronized保护的同步代码块大小合理。
为什么要重点提一下synchronized这个关键字呢?
所以当内置锁可以满足需求时,尽可能使用内置锁,而仅当内置锁无法满足需求(如可中断、可定时、可轮询、公平性等)。简单的来讲,当需要对锁的获取和释放有更精确的控制要求时,考虑使用ReentrantLock。
标签:监视器 避免 而在 互斥 lock java对象 技术 来讲 通过
原文地址:http://www.cnblogs.com/zhangyingai/p/7087358.html