synchronized解析

1、作用:

保证在同一个时刻只能有一个线程运行该段代码(synchronized修饰的代码段或方法),以保证并发安全。

2、用法:

一个类可以有多个的实例对象,一个类只有一个class对象用于描述这个类,根据锁的对象的类型(普通实例对象,class对象)将用法分为对象锁和类锁。

(1)对象锁:锁的对象为普通实例对象,两种形式:(method1,method2) 

方法锁(非static方法的锁对象为this即当前实例对象)和同步代码块锁(指定的锁对象)

(2)类锁:锁的对象为class对象,两种形式:(method3,method4)

修饰static方法(锁对象为当前类的class对象),指定锁为class对象

例子:

synchronized解析

以上例子中method1和method2等价,method3和method4等价

类锁和对象锁的区别:当调用一个类的多个实例对象时,对象锁之间是不会互斥的,但类锁之间存在互斥。

 3、性质

(1)可重入:同一个线程的外层函数获取到锁之后,内层函数可以直接再获取到该锁。可重入能够避免死锁,提高封装性不必再进行多次的加锁解锁操作。

synchronized解析

(2)不可中断:如果一个线程A获取了锁之后,另一个线程B想获取该锁只能选择等待到线程锁A释放该锁,如果线程A一直不释放,那么B线程将永远的等待。线程A释放锁的两种方式:正常运行结束或抛出异常JVM自动释放锁。

4、原理:

(1)加锁释放锁原理:

加锁对应字节码:monitorenter    #第6行对应进入synchronized修饰的代码块

释放锁对应字节码:monitorexit   #第8,14行对应正常运行结束和抛出异常

synchronized解析

(2)可重入性的原理:

通过加锁次数计数器,JVM会记录加锁的次数,每进入一次同步代码块加锁次数计数器会加1,退出一次同步代码块,加锁次数计数器会减1。

5、缺陷:

(1)效率低:锁的释放方式少,试图获取锁时不能设置超时,不能中断一个正在试图获取锁的线程。

(2)不够灵活:加锁和解锁的时机单一,每个锁只有单一的条件(某个对象)

上一篇:android驱动开发,Android详解


下一篇:synchronized 底层如何实现?什么是锁的升级、降级