使用Synchronized块同步方法
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块同步方法相关推荐
- [转载] java synchronized静态同步方法与非静态同步方法,同步语句块
参考链接: Java中的静态方法与实例方法 java synchronized静态同步方法与非静态同步方法,同步语句块 并发编程 线程同步 静态方法锁 非静态方法锁 同步块 进行多线程编程,同步控制是 ...
- Java多线程初学者指南(12):使用Synchronized块同步变量
我们可以通过synchronized块来同步特定的静态或非静态方法.要想实现这种需求必须为这些特性的方法定义一个类变量,然后将这些方法的代码用synchronized块括起来,并将这个类变量作为参数传 ...
- java synchronized静态同步方法与非静态同步方法,同步语句块
大纲:java线程知识体系 对代码进行同步控制我们可以选择同步方法,也可以选择同步块,这两种方式各有优缺点.同步块不仅可以更加精确的控制对象锁,还可以控制锁的作用域,何谓锁的作用域?锁的作用域就是从锁 ...
- java synchronized块_Java多线程同步代码块Synchronized
Java多线程同步代码块Synchronized Java中的每个对象都有一个与之关联的内部锁(Intrinsic lock). 这种锁也称为监视器(Monitor), 这种内部锁是一种排他锁,可以保 ...
- java synchronized 参数_java – 将参数传递给synchronized块的目的是什么?
我知道 When you synchronize a block of code, you specify which object's lock you want to use as the loc ...
- 浅谈一下线程中synchronized块、wait,notify的用法
首先我们来了解一下syncronized块和锁运行的基本原理,我们知道syncronized块的运行是依赖于锁而进行的. 假如把一个对象比喻成一个内部有很多小房子的大房子,有一些小房子没有门,人们随便 ...
- java中receive功能_java - 在onReceive()回调中的synchronized块 - SO中文参考 - www.soinside.com...
我正在阅读this page关于如何编程Android与USB配件通信.其中一个步骤涉及注册BroadcastReceiver以获得用户的许可: IntentFilter filter = new I ...
- java map同步访问_同步 - Java synchronized块与Collections.synchronizedMap
您的代码中可能存在细微的错误. [更新:因为他正在使用map.remove(),所以这种描述并不完全有效. 我第一次错过了这个事实. :(感谢问题的作者指出这一点.我将其余部分保留原样,但改变了主要声 ...
- Java-多线程讲解(2)
目录 线程停止 线程休眠 线程礼让 合并线程 线程优先级 守护线程daemon 线程同步 生产者消费者问题 线程池 线程停止 使用一个标志位终止变量,当flag=false,则线程停止 public ...
最新文章
- 并发异步处理队列 .NET 4.5+
- 推荐系统resys小组线下活动见闻2009-08-22
- 检测到目标服务器启用了trace方法_综述:目标检测中的多尺度检测方法
- TF之DD:利用Inception模型+GD算法生成更大尺寸的Deep Dream精美图片
- HTTP和HTTPS协议及工作原理分析
- tar.gz及tar.bz2两种常见格式的打包压缩及解压方法
- Linux下面MariaDB 管理命令基础使用
- ServerStatus 云探针部署
- 【转载】C++ 内存分配(new,operator new)详解
- ExcelVBA:请注意!文档部分内容可能包含文档检查器无法删除的个人信息。
- 数据结构:新冠病毒检测
- 用计算机进行绘画教案,电脑绘画的教案
- 百度信息流是什么?哪些行业适合投放百度信息流?
- android之学习的网站
- php float 取整,php float 转 int 的问题
- 2017 主流手机分辨率与尺寸
- springboot模板
- 关于checkbox的全选/全不选的处理
- 用MySQL创建数据库和数据库表(linux终端操作)
- 尚不成熟的单个摄像头触屏方案
热门文章
- sqlplus远程连接k8s集群部署的oracle
- k8s基础概念:pause容器和pod控制器类型
- Python Django HttpRequest请求对象常见属性和方法
- Python Django通过牵引文件查看建表sql语句的命令sqlmigrate
- jdk8 List集合 Stream distinct() 去重代码示例
- Java计算两点间经纬度距离(两种方式)
- Mac终端 bash和zsh切换方法
- 【小米面试题】-给定一个具体时间,计算时针与分针之间的角度
- python(matplotlib4)——Scatter 散点图,Bar柱状图(方向:向上,向下),柱状图添加注释
- 键盘按下某键 停止运行java_实现按下一个键执行操作/松开一个键停止操作