转:【Java并发编程】之七:使用synchronized获取互斥锁的几点说明
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17199201
在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确保在某一时刻,方法内只允许有一个线程。
采用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同步块对同一个线程是可重入的,因此一个线程可以多次获得同一个对象的互斥锁,同样,要释放相应次数的该互斥锁,才能最终释放掉该锁。
转:【Java并发编程】之七:使用synchronized获取互斥锁的几点说明的更多相关文章
- Java并发编程实战(3)- 互斥锁
我们在这篇文章中主要讨论如何使用互斥锁来解决并发编程中的原子性问题. 目录 概述 互斥锁模型 互斥锁简易模型 互斥锁改进模型 Java世界中的互斥锁 synchronized中的锁和锁对象 synch ...
- java并发编程实战《三》互斥锁(上)
互斥锁(上):解决原子性问题 原子性问题的源头是线程切换,操作系统做线程切换是依赖 CPU 中断的,所以禁止 CPU 发生中断就能够禁止线程切换. 在早期单核 CPU 时代,这个方案的确是可行的,而且 ...
- java并发编程实战《四》互斥锁(下)
互斥锁(下):如何用一把锁保护多个资源? 一把锁可以保护多个资源,但是不能用多把锁来保护一个资源. 那如何保护多个资源? 当我们要保护多个资源时,首先要区分这些资源是否存在关联关系. 如下代码 ...
- 【Java并发编程】之七:使用synchronized获取互斥锁的几点说明
在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确 ...
- 【Java并发编程】:使用synchronized获取互斥锁
在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确 ...
- java并发编程的艺术(一)---锁的基本属性
本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...
- Java并发编程原理与实战十一:锁重入&自旋锁&死锁
一.锁重入 package com.roocon.thread.t6; public class Demo { /* 当第一个线程A拿到当前实例锁后,进入a方法,那么,线程A还能拿到被当前实例所加锁的 ...
- 使用synchronized获取互斥锁的几点说明
在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确 ...
- 【Java并发编程实战】-----synchronized
在我们的实际应用当中可能经常会遇到这样一个场景:多个线程读或者.写相同的数据,访问相同的文件等等.对于这种情况如果我们不加以控制,是非常容易导致错误的.在java中,为了解决这个问题,引入临界区概念. ...
随机推荐
- c++ 智能指针【转载】
zero 坐在餐桌前,机械的重复“夹菜 -> 咀嚼 -> 吞咽”的动作序列,脸上用无形的大字写着:我心不在焉.在他的对面坐着 Solmyr ,慢条斯理的吃着他那份午餐,维持着他一贯很有修养 ...
- css2--背景
## CSS2 背景##### background-color 设置背景颜色 ##### background-image 设置背景图片- ````background-image:url(&quo ...
- maven系列小技巧之Top3 MVQ(most valuable question)
首先声明,文章系个人原创 ,欢迎转载,转载请注明出处. 对于maven,有大神曾说过:如果你爱他,就请让他用Maven,因为那里是天堂,如果你恨他,就请让他用Maven,因为那里是地狱.尤其是mave ...
- python学习===如何理解python中的return
首先要了解,函数是什么?书上可能会说函数是完成功能的模块之类的话.其实说白了,函数就是个你招来的工人.你给他一些材料,告诉他怎么用这些材料拼装,然后他负责把拼装好的成品交给你.材料就是函数的参数,成品 ...
- HDU 1231 最大连续子序列:水dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1231 题意: 给你一个整数序列,求连续子序列元素之和最大,并输出该序列的首尾元素(若不唯一,输出首坐标 ...
- /dev/null 2>&1解释
/dev/null 2>&1 解释 crontab内容 :50 18 5-30 * * /script/myscript.sh 1> /dev/null 2>&1 其 ...
- Unity3D --对撞机/碰撞器 介绍
碰撞器一般都用作触发器而用,刚体一般用作真实碰撞. 静态对撞机:一个对象有对撞机组件,没有刚体组件. 这种情况在场景中的静态物体应用较多,比如墙体,房屋等静止不动的物体. 物理引擎假设静态对撞机是不会 ...
- HttpServlet源码分析
1.HttpServlet的用法 提供了创建Http Servlet的抽象类,通过实现此类定义自己的Servlet 2.HttpServlet是否是线程安全 先说结论:HttpServlet不是线程安 ...
- Mysql中较为复杂的分组统计去重复值
这是我的代码: 前提是做了一个view:att_sumbase 首先分开统计每天的中午.下午饭点人数,这时需要分别去除中午和下午重复打卡的人.用了记录集的交,嵌套select的知识. 注意不能直接使用 ...
- golang的Channel
golang的Channel Channel 是 golang 一个非常重要的概念,如果你是刚开始使用 golang 的开发者,你可能还没有真正接触这一概念,本篇我们将分析 golang 的Chann ...