Java多线程初学者指南(11):利用Synchronized块同步要领
当前位置:以往代写 > JAVA 教程 >Java多线程初学者指南(11):利用Synchronized块同步要领
2019-06-14

Java多线程初学者指南(11):利用Synchronized块同步要领

Java多线程初学者指南(11):利用Synchronized块同步要领

副标题#e#

synchronized要害字有两种用法。第一种就是在《利用Synchronized要害字同步类要领》一文中所先容的直接用在要领的界说中。别的一种就是synchronized块。我们不只可以通过synchronized块来同步一个工具变量。也可以利用synchronized块来同步类中的静态要领和非静态要领。

synchronized块的语法如下:

public void method()
{
… …
synchronized(表达式)
{
… …
}
}

一、非静态类要领的同步

从《利用Synchronized要害字同步类要领》一文中我们知道利用synchronized要害字来界说要领就会锁定类中所有利用synchronzied要害字界说的静态要领或非静态要领,但这并欠好领略。而假如利用synchronized块来到达同样的结果,就不难领略为什么会发生这种结果了。假如想利用synchronized块来锁定类中所有的同步非静态要领,需要利用this做为synchronized块的参数传入synchronized块国,代码如下:

通过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  }

在上面的代码中的method1和method2要领中利用了synchronized块。而第017行的method3要领仍然利用synchronized要害字来界说要领。在利用同一个SyncBlock类实例时,这三个要领只要有一个正在执行,其他两个要领就会因未得到同步锁而被阻塞。在利用synchronized块时要想到达和synchronized要害字同样的结果,必需将所有的代码都写在synchronized块中,不然,将无法使当前要领中的所有代码和其他的要领同步。

除了利用this做为synchronized块的参数外,还可以利用SyncBlock.this作为synchronized块的参数来到达同样的结果。


#p#副标题#e#

在内类(InnerClass)的要领中利用synchronized块来时,this只暗示内类,和外类(OuterClass)没有干系。但内类的非静态要领可以和外类的非静态要领同步。如在内类InnerClass中加一个method4要领,并使method4要领和SyncBlock的三个要领同步,代码如下:

使内类的非静态要领和外类的非静态要领同步

public class SyncBlock
{
… …
class InnerClass
{
public void method4()
{
synchronized(SyncBlock.this)
{
… … 
}
}
}
… …
}

在上面SyncBlock类的新版本中,InnerClass类的method4要领和SyncBlock类的其他三个要领同步,因此,method1、method2、method3和method4四个要领在同一时间只能有一个要领执行。

Synchronized块不管是正常执行完,照旧因为措施堕落而异常退出synchronized块,当前的synchronized块所持有的同步锁城市自动释放。因此,在利用synchronized块时不必担忧同步锁的释放问题。

二、静态类要领的同步

由于在挪用静态要领时,工具实例不必然被建设。因此,就不能利用this来同步静态要领,而必需利用Class工具来同步静态要领。代码如下:

通过synchronized块同步静态要领

public class StaticSyncBlock
{
public static void method1()
{
synchronized(StaticSyncBlock.class)
{
… …
}
}
public static synchronized void method2()
{
… …
}
}

在同步静态要领时可以利用类的静态字段class来获得Class工具。在上例中method1和method2要领同时只能有一个要领执行。除了利用class字段获得Class工具外,还可以利用实例的getClass要领来获得Class工具。上例中的代码可以修改如下:

利用getClass要领获得Class工具

public class StaticSyncBlock
{
public static StaticSyncBlock instance; 
public StaticSyncBlock()
{
instance = this;
}
public static void method1()
{
synchronized(instance.getClass())
{
Java多线程初学者指南(11):操作Synchronized块同步方式 Java多线程初学者指南(11):操作Synchronized块同步方式
}
}
Java多线程初学者指南(11):操作Synchronized块同步方式 Java多线程初学者指南(11):操作Synchronized块同步方式
}

#p#副标题#e#

#p#分页标题#e#

在上面代码中通过一个public的静态instance获得一个StaticSyncBlock类的实例,并通过这个实例的getClass要领获得了Class工具(一个类的所有实例通过getClass要领获得的都是同一个Class工具,因此,挪用任何一个实例的getClass要领都可以)。我们还可以通过Class工具使差异类的静态要领同步,如Test类的静态要领method和StaticSyncBlock类的两个静态要领同步,代码如下:

Test类的method要领和StaticSyncBlock类的method1、method2要领同步

public class Test
{
public static void method()
{
synchronized(StaticSyncBlock.class)
{
Java多线程初学者指南(11):操作Synchronized块同步方式 Java多线程初学者指南(11):操作Synchronized块同步方式
}
}
}

留意:在利用synchronized块同步类要领时,非静态要领可以利用this来同步,而静态要领必需利用Class工具来同步。它们互不影响。虽然,也可以在非静态要领中利用Class工具来同步静态要领。但在静态要领中不能利用this来同步非静态要领。这一点在利用synchronized块同步类要领时应留意。

    关键字:

在线提交作业