剖析Java同步块synchronized及常用使用方法

来源:互联网 发布:上海东行网络 编辑:程序博客网 时间:2024/04/23 18:15

           Java 同步块(synchronized block)用来标记方法或者代码块是同步,避免线程的资源竞争和数据的不一致问题。


 Java中的同步块用synchronized标记。同步块在Java中是同步在某个对象上。所有同步在这个对象上的同步块在同一时刻只能被一个线程进入并执行操作。

其它对该对象的同步块的线程将被阻塞,直到执行该同步块中的线程执行完成退出。


接下来介绍同步块的四种方式:


实例方法同步


下面是一个同步的实例方法:

public synchronized void add(int number){sum=sum+number;}


在上面的add方法上声明同步(synchronized )关键字,这告诉Java该方法是同步的。这种声明方式是同步在拥有该方法的对象上。这种方式也是在实际的编程中使用的比较多的一种方式

这种方式每个实例其方法同步都同步在不同的对象上,就是该方法所属的实例。通俗点讲就是多个线程对同一个实例的同步块进行调用时,同一时刻只有一个线程在调用。如果有多个实例

多个线程分别对不用的实例同步块进行调用是互不影响的,不会造成等待。

静态方法同步

下面是一个静态方法同步:

<span style="white-space:pre"></span>public static synchronized void add(int number){sum=sum+number;}

静态方法的同步是指同步在该方法所在的类对象上。因为在Java虚拟机中一个类只能对应一个类对象,所以同时只允许一个线程执行同一个类中的静态同步方法。


对于不同类中的静态同步方法,一个线程可以执行每个类中的静态同步方法而无需等待。通俗的说,就是多个线程对类的静态同步方法,同一时刻只允许一个线程对该类的静态


同步方法进行调用。


实例方法中的同步块


有时你不需要同步整个方法,而是同步方法中的一部分。Java可以对方法的一部分进行同步。


在非同步的Java方法中的同步块的例子如下所示:

public void add(int number){synchronized(this){sum=sum+number;}}


该代码在执行时和实例同步方法一样。但是Java同步块需用括号将对象括起来。在上面代码中使用了“this”,即为调用add方法的实例本身。在同步构造器中用括号括起来的对象叫做监视器对象,这个监视器对象可以是this,也可以其它的对象不如string对象等等。上述代码使用监视器对象同步,同步实例方法使用调用方法本身的实例作为监视器对象。


一次只有一个线程能够在同步于同一个监视器对象的Java方法内执行。


静态方法中的同步块


静态方法中的同步块和上面类似,下面是两个静态方法同步的例子。这些方法同步在该方法所属的类对象上。

public class SynStaticTest {private static long sum=0;    public static synchronized void add(long num){       sum=sum+num;   }    public static  void deleye(long num){      synchronized(SynStaticTest.class){sum=sum-num;      }    } }


以上类中的两个方法是不允许同时被线程访问的,也就是说同一时刻只允许调用执行一个方法。
6 0
原创粉丝点击