synchronized 可以用来修饰以下 3 个层面:
- 修饰实例方法;
这种情况下的锁对象是当前实例对象,因此只有同一个实例对象调用此方法才会产生互斥效果,不同实例对象之间不会有互斥效果.
-
修饰静态类方法;
锁的是对象,在不同线程调用,也有互斥效果 -
修饰代码块。
锁对象就是跟在后面括号中的对象
synchronized 既可以作用于方法和作用于代码块的区别:
作用于方法:将方法标记ACC_SYNCHRONIZED,虚拟机自动会开始和结束(或异常)位置添加 monitorenter 和 monitorexit 指令。
作用于代码块:会在字节码中插入 1 个 monitorenter 和 2 个 monitorexit
mon.png
ReentrantLock
默认ynchronized 和 ReentrantLock 都是非公平锁,ReentrantLock构造方法,传true 就是公平锁.
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
所谓公平锁就是通过同步队列来实现多个线程按照申请锁的顺序获取锁;
ReentrantReadWriteLock(读写锁)
要写入数据的时候,获取写入锁,读取的操作都会被阻塞,当写入成功后,读取的操作继续进行,且读取的数据是最新的数据。
网友评论