不久前用到了同步,现在回过头来对JAVA中的同步做个总结,以对前段时间工作的总结和自我技术的条理话。JAVA的synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。假如再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。 
在进一步阐述之前,我们需要明确几点: 
A.无论synchronized关键字加在方法上还是对象上,他取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。 
B.每个对象只有一个锁(lock)和之相关联。 
C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。 
接着来讨论synchronized用到不同地方对代码产生的影响:

假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都能够调用他们。

Java的synchronized使用方法总结

1.  把synchronized当作函数修饰符时,示例代码如下:

  1. Public synchronized void method(){
  2. //….
  3. }

这也就是同步方法,那这时synchronized锁定的是哪个对象呢?他锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。 
上边的示例代码等同于如下代码:

  1. public void method()
  2. {
  3. synchronized (this)      //  (1)
  4. {
  5. //…..
  6. }
  7. }

(1)处的this指的是什么呢?他指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同步机制的控制,造成数据混乱。

2.同步块,示例代码如下:

  1. public void method(SomeObject so) {
  2. synchronized(so)
  3. {
  4. //…..
  5. }
  6. }

这时,锁就是so这个对象,谁拿到这个锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(他得是个对象)来充当锁:

  1. class Foo implements Runnable
  2. {
  3. private byte[] lock = new byte[0];  // 特别的instance变量
  4. Public void method()
  5. {
  6. synchronized(lock) { //… }
  7. }
  8. //…..
  9. }

注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。

3.将synchronized作用于static 函数,示例代码如下:

  1. Class Foo
  2. {
  3. public synchronized static void method1()   // 同步的static 函数
  4. {
  5. //….
  6. }
  7. public void method2()
  8. {
  9. synchronized(Foo.class)   //  class literal(类名称字面常量)
  10. }
  11. }

代码中的method2()方法是把class literal作为锁的情况,他和同步的static函数产生的效果是相同的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。 
记得在《Effective Java》一书中看到过将 Foo.class和 P1.getClass()用于作同步锁还不相同,不能用P1.getClass()来达到锁这个Class的目的。P1指的是由Foo类产生的对象。 
能够推断:假如一个类中定义了一个synchronized的static函数A,也定义了一个synchronized 的instance函数B,那么这个类的同一对象Obj在多线程中分别访问A和B两个方法时,不会构成同步,因为他们的锁都不相同。A方法的锁是Obj所属的那个Class,而B的锁是Obj所属的这个对象。

Java的synchronized使用方法小结如下:

搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程式。

更有一些技巧能够让我们对共享资源的同步访问更加安全: 
1.  定义private 的instance变量+他的 get方法,而不要定义public/protected的instance变量。假如将变量定义为public,对象在外界能够绕过同步方法的控制而直接取得他,并改变他。这也是JavaBean的标准实现方式之一。 
2.  假如instance变量是个对象,如数组或ArrayList什么的,那上述方法仍然不安全,因为当外界对象通过get方法拿到这个instance对象的引用后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很危险。 这个时候就需要将get方法也加上synchronized同步,并且,只返回这个private对象的clone()――这样,调用端得到的就是对象副本的引用了。

from: http://developer.51cto.com/art/200908/143504.htm

Java的synchronized关键字:同步机制总结相关推荐

  1. java的同步关键字_简单了解Java synchronized关键字同步

    简单了解Java synchronized关键字同步 发布于 2021-1-13| 复制链接 摘记:  synchronized synchronized可以用来同步块,同步方法.同步块可以用来更精确 ...

  2. Java多线程之线程同步机制(锁,线程池等等)

    Java多线程之线程同步机制 一.概念 1.并发 2.起因 3.缺点 二.三大不安全案例 1.样例一(模拟买票场景) 2.样例二(模拟取钱场景) 3.样例三(模拟集合) 三.同步方法及同步块 1.同步 ...

  3. java 死锁 内存消耗_详解Java中synchronized关键字的死锁和内存占用问题

    先看一段synchronized 的详解: synchronized 是 java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并 ...

  4. 从分布式锁角度理解Java的synchronized关键字

    分布式锁 分布式锁就以zookeeper为例,zookeeper是一个分布式系统的协调器,我们将其理解为一个文件系统,可以在zookeeper服务器中创建或删除文件夹或文件.设D为一个数据系统,不具备 ...

  5. JAVA synchronized关键字锁机制(中)

    synchronized 锁机制简单的用法,高效的执行效率使成为解决线程安全的首选. 下面总结其特性以及使用技巧,加深对其理解. 特性: 1. Java语言的关键字,当它用来修饰一个方法或者一个代码块 ...

  6. Java多线程初学者指南(10):使用Synchronized关键字同步类方法

    要想解决"脏数据"的问题,最简单的方法就是使用synchronized关键字来使run方法同步,代码如下: public synchronized void run() {     ...

  7. 【Java】synchronized关键字笔记

    Java Synchronized 关键字 壹. Java并发编程存在的问题 1. 可见性问题 可见性问题是指一个线程不能立刻拿到另外一个线程对共享变量的修改的结果. 如: package Note. ...

  8. Java并发——Synchronized关键字和锁升级,详细分析偏向锁和轻量级锁的升级

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/tongdanping/article/ ...

  9. Java中 synchronized 关键字的理解

    synchronized 关键字的理解 在Java中,synchronized 是一个重量级的控制并发的关键字. 这个关键字可以保证并发过程所必须的"原子性","可见性& ...

最新文章

  1. javascript requestAnimationFrame 解决 setTimeout、setInterval 时间不准的方法。
  2. Opencv 去高光或镜面反射(illuminationChange)
  3. 整理了一下linux/ubuntu里面卸载软件的方法
  4. 关于SOCKET资源堆栈
  5. 上架APPStore需要准备哪些材料?
  6. idea开启自动热部署自动化devtools
  7. Eclipse和Intel idea的常用技巧
  8. 加密狗通过USB SERVER远程连接
  9. pip install 报错:ERROR: Exception: Traceback (most recent call last):..raise ValueError(“check_hostnam
  10. 图像处理-1 带色彩恢复的多尺度视网膜增强算法
  11. JS实现多张图片绕中心点转动
  12. 2019年最新出搜索引擎蜘蛛网页爬虫大全
  13. 命令行退出python方法
  14. python求f的倒数_Python中整数的倒数
  15. 与小米一起“星辰大海,云端漫步”
  16. 计算机毕业设计Python+djang的图书馆图书借阅归还管理系统(源码+系统+mysql数据库+Lw文档)
  17. 某游戏社区App | So层逆向分析
  18. 坚果pro2 android 版本,坚果Pro2有哪些版本_坚果Pro2内存多大-太平洋IT百科
  19. 面向对象的特征二 继承性
  20. 圣诞节海报没有想法?气氛素材即为切入点

热门文章

  1. Java 编程的动态性,第 8 部分: 用代码生成取代反射--转载
  2. 机器学习算法基础——数据降维
  3. 信用评分卡模型开发及评估指标
  4. var_export
  5. 今年美国广告程序化购买支出将超252亿美元
  6. 徐博 From RankNet to LambdaRank to LambdaMART: An Overview
  7. 人脸特征点定位之Explicit Shape Regression
  8. 数据分层/ODS/DW/DM
  9. 也谈1+2+3+...+n的解答
  10. 深入理解分布式技术 - 先更新数据库,还是先更新缓存