synchronized关键字永远同步java类中的静态方法和非静态方法,基本有synchronized同步方法和synchronized同步块两种方法(参考教程)。
同步方法
1.synchronized关键字只能用来同步方法,不能用来同步类变量
2.synchronized关键字可以同步类中静态与非静态方法,关键字地位置只需要在返回类型之前即可。
3.虽然表面上看起来synchronized关键字修饰、同步的只是一个方法,但它其实是锁定的整个类,就如同数据库中的表一样。
4.由于synchronized关键字同步方法时是锁定的整个类,所以同一个类中用synchronized关键字定义的静态或非静态方法运行时具有唯一性,即所以用
synchronized关键字定义的类方法处于同步锁定状态,禁止同时执行,静态方法同上,但静态与非静态方法互不冲突。
5.在定义接口方法时不能使用synchronized关键字。
同步块
1.可以通过synchronized块来同步一个对象变量。也可以使用synchronized块来同步类中的静态方法和非静态方法。
2.类方法中使用synchronized同步块是需要传入this关键字代替当前类对象
例:通过synchronized块同步非静态方法
001 public class SyncBlock
002 {
003 public void method1()
004 {
005 synchronized(this) // 相当于对method1方法使用synchronized关键字
006 {
007 … …
008 }
009 }
010 public void method2()
011 {
012 synchronized(this) // 相当于对method2方法使用synchronized关键字
013 {
014 … …
015 }
016 }
017 public synchronized void method3()
018 {
019 … …
020 }
021 }
3.
除了使用this做为synchronized块的参数外,还可以使用SyncBlock.this作为synchronized块的参数来达到同样的效果。
在内类(InnerClass)的方法中使用synchronized块来时,this只表示内类,和外类(OuterClass)没有关系。但内类的非静态方法可以和外 类的非静态方法同步。如在内类InnerClass中加一个method4方法,并使method4方法和SyncBlock的三个方法同步,代码如下:
public class SyncBlock
{
… …
class InnerClass
{
public void method4()
{
synchronized(SyncBlock.this)
{
… …
}
}
}
… …
}
4. 由于在调用静态方法时,对象实例不一定被创建。因此,就不能使用this来同步静态方法,而必须使用Class对象来同步静态方法。
例:通过synchronized块同步静态方法
public class StaticSyncBlock
{
public static void method1()
{
synchronized(StaticSyncBlock.class)
{
… …
}
}
public static synchronized void method2()
{
… …
}
}
5. 除了使用class字段得到Class对象外,还可以使用实例的getClass方法来得到Class对象。上例中的代码可以修改如下
public class StaticSyncBlock
{
public static StaticSyncBlock instance;
public StaticSyncBlock()
{
instance = this;
}
public static void method1()
{
synchronized(instance.getClass())
{
}
}
}
上面这个实例表明可以通过类对象得到class对象,即说明可以通过不同类的对象来同步外部类的静态方法。比如可以在A类中的静态方法块中通过传入B类对象.getClass()来达到同时同步A类静态方法。
注意:在使用synchronized块同步类方法时,非静态方法可以使用this来同步,而静态方法必须使用Class对象来同步。它们互不影响。当然,也可以在非静态方法中使用Class对象来同步静态方法。但在静态方法中不能使用this来同步非静态方法。这一点在使用synchronized块同步类方法时应注意。