在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确保在某一时刻,方法内只允许有一个线程。

采用synchronized修饰符实现的同步机制叫做互斥锁机制,它所获得的锁叫做互斥锁。每个对象都有一个monitor(锁标记),当线程拥有这个锁标记时才能访问这个资源,没有锁标记便进入锁池。任何一个对象系统都会为其创建一个互斥锁,这个锁是为了分配给线程的,防止打断原子操作。每个对象的锁只能分配给一个线程,因此叫做互斥锁。

这里就使用同步机制获取互斥锁的情况,进行几点说明:

1、如果同一个方法内同时有两个或更多线程,则每个线程有自己的局部变量拷贝。

2、类的每个实例都有自己的对象级别锁。当一个线程访问实例对象中的synchronized同步代码块或同步方法时,该线程便获取了该实例的对象级别锁,其他线程这时如果要访问synchronized同步代码块或同步方法,便需要阻塞等待,直到前面的线程从同步代码块或方法中退出,释放掉了该对象级别锁。

3、访问同一个类的不同实例对象中的同步代码块,不存在阻塞等待获取对象锁的问题,因为它们获取的是各自实例的对象级别锁,相互之间没有影响。

4、持有一个对象级别锁不会阻止该线程被交换出来,也不会阻塞其他线程访问同一示例对象中的非synchronized代码。当一个线程A持有一个对象级别锁(即进入了synchronized修饰的代码块或方法中)时,线程也有可能被交换出去,此时线程B有可能获取执行该对象中代码的时间,但它只能执行非同步代码(没有用synchronized修饰),当执行到同步代码时,便会被阻塞,此时可能线程规划器又让A线程运行,A线程继续持有对象级别锁,当A线程退出同步代码时(即释放了对象级别锁),如果B线程此时再运行,便会获得该对象级别锁,从而执行synchronized中的代码。

5、持有对象级别锁的线程会让其他线程阻塞在所有的synchronized代码外。例如,在一个类中有三个synchronized方法a,b,c,当线程A正在执行一个实例对象M中的方法a时,它便获得了该对象级别锁,那么其他的线程在执行同一实例对象(即对象M)中的代码时,便会在所有的synchronized方法处阻塞,即在方法a,b,c处都要被阻塞,等线程A释放掉对象级别锁时,其他的线程才可以去执行方法a,b或者c中的代码,从而获得该对象级别锁。

6、使用synchronized(obj)同步语句块,可以获取指定对象上的对象级别锁。obj为对象的引用,如果获取了obj对象上的对象级别锁,在并发访问obj对象时时,便会在其synchronized代码处阻塞等待,直到获取到该obj对象的对象级别锁。当obj为this时,便是获取当前对象的对象级别锁。

7、类级别锁被特定类的所有示例共享,它用于控制对static成员变量以及static方法的并发访问。具体用法与对象级别锁相似。

8、互斥是实现同步的一种手段,临界区、互斥量和信号量都是主要的互斥实现方式。synchronized关键字经过编译后,会在同步块的前后分别形成monitorenter和monitorexit这两个字节码指令。根据虚拟机规范的要求,在执行monitorenter指令时,首先要尝试获取对象的锁,如果获得了锁,把锁的计数器加1,相应地,在执行monitorexit指令时会将锁计数器减1,当计数器为0时,锁便被释放了。由于synchronized同步块对同一个线程是可重入的,因此一个线程可以多次获得同一个对象的互斥锁,同样,要释放相应次数的该互斥锁,才能最终释放掉该锁。

转载于:https://www.cnblogs.com/web424/p/6807597.html

【Java并发编程】:使用synchronized获取互斥锁相关推荐

  1. Java并发编程(7):使用synchronized获取互斥锁的几点说明

    在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确 ...

  2. Java 并发编程:Synchronized 及其实现原理

    作者:liuxiaopeng 原文链接: www.cnblogs.com/paddix/p/5367116.html 一.Synchronized的基本使用 Synchronized是Java中解决并 ...

  3. Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)

    一.重量级锁 上篇文章中向大家介绍了Synchronized的用法及其实现的原理.现在我们应该知道,Synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的.但是监视器锁本质 ...

  4. Java并发编程:synchronized

    虽然多线程编程极大地提高了效率,但是也会带来一定的隐患.比如说两个线程同时往一个数据库表中插入不重复的数据,就可能会导致数据库中插入了相同的数据.今天我们就来一起讨论下线程安全问题,以及Java中提供 ...

  5. Java并发编程实例(synchronized)

    此处用一个小程序来说明一下,逻辑是一个计数器(int i):主要的逻辑功能是,如果同步监视了资源i,则不输出i的值,但如果没有添加关键字synchronized,因为是两个线程并发执行,所以会输出i的 ...

  6. 并发编程的艺术03-Bakery互斥锁算法

    3 月,跳不动了?>>> 导读 本章会介绍Bakery互斥锁算法,涉及到并发下的公平性问题,有界计数器和无界计数器问题, 存储单元数量下界问题. 公平性 无饥饿特性能够保证每一个调用 ...

  7. 学习笔记(26):Python网络编程并发编程-GIL与自定义互斥锁的区别

    立即学习:https://edu.csdn.net/course/play/24458/296443?utm_source=blogtoedu 1.GIL的基本概念 答:GIL本质上就是一把锁,只是他 ...

  8. Java 并发编程之可重入锁 ReentrantLock

    Java 提供了另外一个可重入锁,ReentrantLock,位于 java.util.concurrent.locks 包下,可以替代 synchronized,并且提供了比 synchronize ...

  9. Java并发编程-ReentrantLock可重入锁

    目录 1.ReentrantLock可重入锁概述 2.可重入 3.可打断 4.锁超时 5.公平锁 6.条件变量 Condition 1.ReentrantLock可重入锁概述 相对于 synchron ...

最新文章

  1. Accurate self-correction of errors inlong reads using de Bruijn graphs LoRMA使用de Bruijn图对长read中的错误
  2. Oracle创建数据库(手动)
  3. iOS高级教程:处理1000张图片的内存优化
  4. 【python练习】基于socket的FTP程序 v1.1.0(支持多用户)
  5. 软件工程 / 为什么基于接口而非实现编程?
  6. php中new意思,php 在一个类中new自己代表什么意思 ?是构造函数
  7. C# 委托(Delegate) 事件(Event)应用详解
  8. 洛谷 P1313 计算系数 Label:杨辉三角形 多项式计算
  9. SAS和SATA硬盘的区别
  10. 评《货币战争》:问苍茫大地谁主沉浮? 第一次转这样的帖子
  11. umpy知识点补充:np.vstack()np.hstack()
  12. 运行c程序的步骤及方法
  13. Vivado中各个文件的含义
  14. 题解 P2916 【[USACO08NOV]安慰奶牛Cheering up the Cow】
  15. 经济学中的100个基本概念
  16. MXNet网络模型(四)GAN神经网络
  17. 为笔记本添加固态硬盘以及之后的分区方法分享
  18. 智能家居一智能插座 Homekit
  19. Python爬虫编程12——字体反爬
  20. 线性位置检测 - CHI612替代TLE4997、MLX90251

热门文章

  1. php domdocument getelementbyid,PHP DOMDocument- getElementByID添加Â代替空
  2. 反射与泛型 java_Java的反射 和 泛型的一个问题
  3. 如何写一个简单的node.js C 扩展
  4. linux vim自动换行,VIM 的自动换行及自动折行设置
  5. quartz java 线程 不释放_java Quartz 内存泄漏
  6. java 区号_求您!JAVA作业,窗口查询区号!
  7. 工业级光纤收发器如何正确使用和维护?
  8. 【渝粤教育】国家开放大学2018年秋季 2508T学前儿童语言教育 参考试题
  9. Wi-Fi和WLAN有什么区别
  10. log4j 禁止类输出日志_log4j 2过滤spring日志遇到的问题