synchronized关键字是Java支持的锁,始终要保证临界区的访问控制。所谓临界区就是指访问这个地方最多只有一个线程。Synchronized是通过在对象上加锁后进入临界区来达到临界区串行访问的目的,而对象本身的作用域将决定锁的粒度。
synchronized是对类的当前实例进行加锁,目的是防止其他线程同时访问该类的该实例的所有synchronized块。
static synchronized是限制线程同时访问JVM中该类的所有实例同时访问对应的代码块。
synchronized相对于this.synchronized,static synchronized相对于something.synchronized。
《Java多线程设计模式》中的一个例子:
public class Something{
public synchronized void isSyncA(){}
public synchronized void isSyncB(){}
public static synchronized void cSyncA(){}
public static synchronized void cSyncB(){}
}
假如Something类有两个实例x与y,下列组合是否可以被一个以上的线程同时访问?
A:x.isSyncA() 与x.isSyncB()
解析:都是对同一实例的synchronized域访问,因此不能被同时访问。
B:x.isSyncA()与y.isSyncA()
解析:是针对不同实例的,因此可以被同时访问。
C:x.cSynchA()与y.cSyncB()
解析:因为是static synchronized,所以不同实例之间仍然会被限制,相当于Somthing.isSyncA()与Something.isSyncB(),因此不同被同时访问。
D:x.isSyncA()与Something.cSyncA()
解析:synchronized的是实例方法与synchronized的类方法由于锁定的是不同的,所以可以被同时访问。
结论:static synchronized是某个类的范围,synchronized static cSync(){} 防止多个线程同时访问这个类中的static synchronized方法。它可以对类的所有对象实例起作用。
synchronized是某实例的范围,synchronized isSync(){}防止多个线程同时访问这个实例中的synchronized方法。
Thinking in java的中文版本中,也有如下说明:
synchronized关键字的作用域如下两种:
(1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的synchronized方法,其他线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相互干扰的。也就是说,其他线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
(2)是某个类的访问,synchronized static aStaticmethod{}防止多个线程同时访问这个类中的synchronized static方法。它可以对类的所有对象实例起作用。
另外,除了在方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是:synchronized(this){/*区块*/},它的作用域是当前对象。
synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要显式的指定它的某个方法为synchronized方法。
这篇博文参考了:http://www.cnblogs.com/shipengzhi/articles/2223100.html