一、概念
1. Synchronized释义:
synchronized 中文释义使同步化。
2. 一句话说出Synchronized的作用:
能够保证在同一时刻最多只有一个线程执行某段代码,以达到保证并发安全的效果。
3. 不使用并发的后果:
案例:两个线程,同时分别对一条数据进行累加10万次。
结果:最终,i值小于20万。
结果分析:i++的过程可分为三步:①从内存中读取i值;②i值加一;③将i值写入内存;场景重现:当线程1读取到i值(假设为9)然后给i值加一时,线程2进入了并读取i值(此时读取到的i值和线程1读取到的一样,为9)然后给i值加一,然后线程1和线程2分别保存i值(10),此时就丢失了一次i++的值,故造成数据的丢失。
二、Synchronized的两种用法
1. 对象锁
①同步代码块锁:可以手动指定锁对象
②方法锁:synchronized修饰普通方法,锁对象默认为this
2. 类锁
概念:同一个Java对象,可以有多个实例,但是只有一个Class对象
①synchronized加在static方法上:
②synchronized(*.class)代码块:
三、Synchronized的性质
1. 可重入
什么是可重入?答:指的是同一线程的外层函数获得锁之后,内层函数可以直接再次获取该锁。
可重入的好处在哪?答:避免死锁、提高封装性
粒度:线程而非调用
2. 不可中断
什么是不可中断?答:一旦一个锁被别的线程获得了,如果我还想获得,那么我就只能选择等待或者阻塞,直到别的线程释放这个锁。(如果别人永远不释放锁,那么我只能永远等下去)
相比之下,JDK中的Lock锁,具有中断的能力。第一,如果我觉得等待时间太长了,有权中断现在已经获取到锁的线程的执行;第二,如果我觉得等待时间太长了不想等了,也可以退出。
四、Synchronized的缺陷
1. 效率低:锁的释放情况少、试图获得锁时不能设定超时、不能中断一个正在试图获得锁的线程。
2. 不够灵活:加锁和释放的时机单一,每个锁仅有单一的条件
3. 不够明确:无法知道是否成功获取到锁