当前位置:网站首页>Synchronized关键字详解
Synchronized关键字详解
2022-07-29 00:06:00 【Kevin张俊杰】
前言
线程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要诱因有两点:
- 一是存在共享数据(也称临界资源)
- 二是存在多条线程共同操作共享数据
因此为了解决这个问题,我们可能需要这样一个方案,当存在多个线程操作共享数据时,需要保证同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再进行,这种方式有个高尚的名称叫互斥锁,即能达到互斥访问目的的锁,也就是说当一个共享数据被当前正在访问的线程加上互斥锁后,在同一个时刻,其他线程只能处于等待的状态,直到当前线程处理完毕释放该锁。
在 Java 中,关键字 synchronized可以保证在同一个时刻,只有一个线程可以执行某个方法或者某个代码块(主要是对方法或者代码块中存在共享数据的操作),同时我们还应该注意到synchronized另外一个重要的作用,synchronized可保证一个线程的变化(主要是共享数据的变化)被其他线程所看到(保证可见性,完全可以替代Volatile功能),这点确实也是很重要的。
Synchronized的使用
一把锁只能同时被一个线程获取,没有获得锁的线程只能等待;
每个实例都对应有自己的一把锁(this),不同实例之间互不影响;例外:锁对象是*.class以及synchronized修饰的是static方法的时候,所有对象公用同一把锁
synchronized修饰的方法,无论方法正常执行完毕还是抛出异常,都会释放锁
对象锁
包括方法锁(默认锁对象为this,当前实例对象)和同步代码块锁(自己指定锁对象)
代码块形式:手动指定锁定对象,也可是是this,也可以是自定义的锁
方法锁形式:synchronized修饰普通方法,锁对象默认为this
类锁
指synchronize修饰静态的方法或指定锁对象为Class对象
synchronize修饰静态方法
synchronized指定锁对象为Class对象
深入理解Synchronized
使用Synchronized有哪些要注意的
锁对象不能为空,因为锁的信息都保存在对象头里
作用域不宜过大,影响程序执行的速度,控制范围过大,编写代码也容易出错
避免死锁
在能选择的情况下,既不要用Lock也不要用synchronized关键字,用java.util.concurrent包中的各种各样的类
synchronized是公平锁吗
synchronized实际上是非公平的,新来的线程有可能立即获得监视器,而在等待区中等候已久的线程可能再次等待,这样有利于提高性能,但是也可能会导致饥饿现象。
Synchronized的缺陷
效率低:锁的释放情况少,只有代码执行完毕或者异常结束才会释放锁;
试图获取锁的时候不能设定超时,不能中断一个正在使用锁的线程,相对而言,Lock可以中断和设置超时;
不够灵活:加锁和释放的时机单一,每个锁仅有一个单一的条件(某个对象),相对而言,读写锁更加灵活
无法知道是否成功获得锁,相对而言,Lock可以拿到状态
Lock解决相应问题
Lock类这里不做过多解释,主要看里面的4个方法:
lock(): 加锁
unlock(): 解锁
tryLock(): 尝试获取锁,返回一个boolean值
tryLock(long,TimeUtil): 尝试获取锁,可以设置超时 Synchronized只有锁只与一个条件(是否获取锁)相关联,不灵活,后来Condition与Lock的结合解决了这个问题。
多线程竞争一个锁时,其余未得到锁的线程只能不停的尝试获得锁,而不能中断。高并发的情况下会导致性能下降。ReentrantLock
的lockInterruptibly()
方法可以优先考虑响应中断。 一个线程等待时间过长,它可以中断自己,然后ReentrantLock响应这个中断,不再让这个线程继续等待。有了这个机制,使用ReentrantLock时就不会像synchronized那样产生死锁了。
ReentrantLock为常用类,它是一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。
使用@guardedby同步注解
@GuardedBy( "this" )
受对象内部锁保护@GuardedBy( "fieldName" )
受与fieldName引用相关联的锁保护@GuardedBy( "ClassName.fieldName" )
受一个类的静态field的锁保存@GuardedBy( "methodName()" )
锁对象是methodName()方法的返值,受这个锁保护@GuardedBy( "ClassName.class" )
受ClassName类的直接锁对象保护,而不是这个类的某个实例的锁对象
边栏推荐
- Consumer unit
- Inftnews | yuanuniverse shopping experience will become a powerful tool to attract consumers
- [untitled]
- 消费行业数字化升级成“刚需”,weiit新零售SaaS为企业赋能!
- The method of tracking the real-time market of London Silver
- “index [hotel/jXLK5MTYTU-jO9WzJNob4w] already exists“
- NFT 项目的 7 种市场营销策略
- 转:认知亚文化
- SystemVerilog-连接和复制运算符
- [Commons lang3 topic] 005- objectutils topic
猜你喜欢
Deep learning | matlab implementation of TCN time convolution neural network spatialdropoutlayer parameter description
如何执行建设项目的时间影响分析?
State compression DP Mondrian's dream
教你一文解决 js 数字精度丢失问题
SystemVerilog join and copy operators
[untitled]
Visual full link log tracking
Univariate function integration 1__ Indefinite integral
[web development] basic knowledge of flask framework
【unity】将unity编辑c#配置为vscode
随机推荐
Day2:三种语言暴刷牛客130题
RHCE命令练习(二)
Instruction rearrangement, happens before, as if serial
机器学习 | MATLAB实现RBF径向基神经网络newrbe参数设定
正则表达式
Solid smart contract tutorial (5) -nft auction contract
Deep learning | matlab implementation of TCN time convolution neural network spatialdropoutlayer parameter description
小程序毕设作品之微信校园浴室预约小程序毕业设计成品(5)任务书
“index [hotel/jXLK5MTYTU-jO9WzJNob4w] already exists“
Daniel guild Games: summary and future outlook of this year
SystemVerilog-连接和复制运算符
Beginner's Guide to electronic bidding
PLATO上线LAAS协议Elephant Swap,用户可借此获得溢价收益
【Leetcode-滑动窗口问题】
一元函数积分学之1__不定积分
Tupu software appeared at the 2022 Fuzhou digital Expo to jointly create a new digital era
QT static compiler (MinGW compilation)
regular expression
FLV文件简介
How to carry out engineering implementation of DDD Domain Driven Design