synchronized关键字有两种用法。第一种就是在《使用Synchronized关键字同步类方法》一文中所介绍的直接用在方法的定义中。另外一种就是synchronized块。我们不仅可以通过synchronized块来同步一个对象变量。也可以使用synchronized块来同步类中的静态方法和非静态方法。

synchronized块的语法如下:


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

一、非静态类方法的同步

从《使用Synchronized关键字同步类方法》一文中我们知道使用synchronized关键字来定义方法就会锁定类中所有使用synchronzied关键字定义的静态方法或非静态方法,但这并不好理解。而如果使用synchronized块来达到同样的效果,就不难理解为什么会产生这种效果了。如果想使用synchronized块来锁定类中所有的同步非静态方法,需要使用this做为synchronized块的参数传入synchronized块国,代码如下:

通过synchronized块同步非静态方法


public class SyncBlock  {  public void method1() { synchronized(this) // 相当于对method1方法使用synchronized关键字 { … … } } public void method2() { synchronized(this) // 相当于对method2方法使用synchronized关键字 { … … } } public synchronized void method3() { … … } } 

在上面的代码中的method1和method2方法中使用了synchronized块。而第017行的method3方法仍然使用synchronized关键字来定义方法。在使用同一个SyncBlock类实例时,这三个方法只要有一个正在执行,其他两个方法就会因未获得同步锁而被阻塞。在使用synchronized块时要想达到和synchronized关键字同样的效果,必须将所有的代码都写在synchronized块中,否则,将无法使当前方法中的所有代码和其他的方法同步。

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

在内部类(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()) { } } } 

在上面代码中通过一个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) { } } } 

注意:在使用synchronized块同步类方法时,非静态方法可以使用this来同步,而静态方法必须使用Class对象来同步。它们互不影响。当然,也可以在非静态方法中使用Class对象来同步静态方法。但在静态方法中不能使用this来同步非静态方法。这一点在使用synchronized块同步类方法时应注意。

转载于:https://www.cnblogs.com/yuyu666/p/9741434.html

使用Synchronized块同步方法相关推荐

  1. [转载] java synchronized静态同步方法与非静态同步方法,同步语句块

    参考链接: Java中的静态方法与实例方法 java synchronized静态同步方法与非静态同步方法,同步语句块 并发编程 线程同步 静态方法锁 非静态方法锁 同步块 进行多线程编程,同步控制是 ...

  2. Java多线程初学者指南(12):使用Synchronized块同步变量

    我们可以通过synchronized块来同步特定的静态或非静态方法.要想实现这种需求必须为这些特性的方法定义一个类变量,然后将这些方法的代码用synchronized块括起来,并将这个类变量作为参数传 ...

  3. java synchronized静态同步方法与非静态同步方法,同步语句块

    大纲:java线程知识体系 对代码进行同步控制我们可以选择同步方法,也可以选择同步块,这两种方式各有优缺点.同步块不仅可以更加精确的控制对象锁,还可以控制锁的作用域,何谓锁的作用域?锁的作用域就是从锁 ...

  4. java synchronized块_Java多线程同步代码块Synchronized

    Java多线程同步代码块Synchronized Java中的每个对象都有一个与之关联的内部锁(Intrinsic lock). 这种锁也称为监视器(Monitor), 这种内部锁是一种排他锁,可以保 ...

  5. java synchronized 参数_java – 将参数传递给synchronized块的目的是什么?

    我知道 When you synchronize a block of code, you specify which object's lock you want to use as the loc ...

  6. 浅谈一下线程中synchronized块、wait,notify的用法

    首先我们来了解一下syncronized块和锁运行的基本原理,我们知道syncronized块的运行是依赖于锁而进行的. 假如把一个对象比喻成一个内部有很多小房子的大房子,有一些小房子没有门,人们随便 ...

  7. java中receive功能_java - 在onReceive()回调中的synchronized块 - SO中文参考 - www.soinside.com...

    我正在阅读this page关于如何编程Android与USB配件通信.其中一个步骤涉及注册BroadcastReceiver以获得用户的许可: IntentFilter filter = new I ...

  8. java map同步访问_同步 - Java synchronized块与Collections.synchronizedMap

    您的代码中可能存在细微的错误. [更新:因为他正在使用map.remove(),所以这种描述并不完全有效. 我第一次错过了这个事实. :(感谢问题的作者指出这一点.我将其余部分保留原样,但改变了主要声 ...

  9. Java-多线程讲解(2)

    目录 线程停止 线程休眠 线程礼让 合并线程 线程优先级 守护线程daemon 线程同步 生产者消费者问题 线程池 线程停止 使用一个标志位终止变量,当flag=false,则线程停止 public ...

最新文章

  1. 并发异步处理队列 .NET 4.5+
  2. 推荐系统resys小组线下活动见闻2009-08-22
  3. 检测到目标服务器启用了trace方法_综述:目标检测中的多尺度检测方法
  4. TF之DD:利用Inception模型+GD算法生成更大尺寸的Deep Dream精美图片
  5. HTTP和HTTPS协议及工作原理分析
  6. tar.gz及tar.bz2两种常见格式的打包压缩及解压方法
  7. Linux下面MariaDB 管理命令基础使用
  8. ServerStatus 云探针部署
  9. 【转载】C++ 内存分配(new,operator new)详解
  10. ExcelVBA:请注意!文档部分内容可能包含文档检查器无法删除的个人信息。
  11. 数据结构:新冠病毒检测
  12. 用计算机进行绘画教案,电脑绘画的教案
  13. 百度信息流是什么?哪些行业适合投放百度信息流?
  14. android之学习的网站
  15. php float 取整,php float 转 int 的问题
  16. 2017 主流手机分辨率与尺寸
  17. springboot模板
  18. 关于checkbox的全选/全不选的处理
  19. 用MySQL创建数据库和数据库表(linux终端操作)
  20. 尚不成熟的单个摄像头触屏方案

热门文章

  1. sqlplus远程连接k8s集群部署的oracle
  2. k8s基础概念:pause容器和pod控制器类型
  3. Python Django HttpRequest请求对象常见属性和方法
  4. Python Django通过牵引文件查看建表sql语句的命令sqlmigrate
  5. jdk8 List集合 Stream distinct() 去重代码示例
  6. Java计算两点间经纬度距离(两种方式)
  7. Mac终端 bash和zsh切换方法
  8. 【小米面试题】-给定一个具体时间,计算时针与分针之间的角度
  9. python(matplotlib4)——Scatter 散点图,Bar柱状图(方向:向上,向下),柱状图添加注释
  10. 键盘按下某键 停止运行java_实现按下一个键执行操作/松开一个键停止操作