公平锁VS非公平锁
- 公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得,例如每个线程抢占锁的顺序为先后调用lock方法的顺序依次获取锁,类似于排队吃饭。
非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待,例如每个线程抢占锁的顺序不定,谁运气好,谁就获取到锁,和调用lock方法的先后顺序无关,类似于堵车时,加塞的那些XXXX。
synchronized就是非公平锁,它无法保证等待的线程获取锁的顺序;
ReentrantLock 默认的lock()方法采用的是非公平锁,但可以选择公平锁实现的方式。
public ReentrantLock(boolean fair) //根据参数初始化为公平锁或者非公平锁
{
sync = fair ? new FairSync() : new NonfairSync();
}
Volatile
- 通过java内存模型(JMM)保证volatile的可见性和有序性。编译器和处理器不会对存在数据依赖关系的操作做重排序,因为这种重排序会改变执行结果。而线程与线程之间使用的是共享变量的副本,副本没有依赖关系导致线程间可能出现重排序的问题;
- JMM通过java进程之间的通信,控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证;
- Volatile通过内存屏障保证写的数据即时刷新到主内存,来防止线程间的重排序问题。
内存屏障的作用:
- 阻止屏障两边的指令重排序;
- 强制把写缓冲区/高速缓存中的脏数据等写回主内存,让缓存中相应的数据失效。
对Load Barrier来说,在读指令前插入读屏障,可以让高速缓存中的数据失效,重新从主内存加载数据;
对Store Barrier来说,在写指令之后插入写屏障,能让写入缓存的最新数据写回到主内存。
锁的一些基本概念
最新推荐文章于 2022-03-17 15:45:30 发布