synchronized
-
syncronized 基于mutex 互斥变量实现的
-
一旦用到mutex需要就需要上下文(context)切换(线程睡眠再唤醒)
-
上下文的切换就意味着内核态和用户态的切换
-
硬件的调用必须在内核态的状态下才能完成,这样做是为了保证安全
-
-
因为mutex有上下文切换所以他慢
-
-
syncronized是一个可重入的非公平锁
ReentrantLock
-
ReetrantLock是一个可重入的独占锁,主要有两个特性,一个是支持公平锁和非公平锁,一个是可重入
-
ReetrantLock实现依赖于AQS(AbstractQueuedSynchronizer),ReetrantLock主要依靠AQS维护一个阻塞队列,多个线程对加锁时,失败则会进入阻塞队列,等待唤醒,重新尝试加锁。
synchronized 和ReentrantLock的区别?
-
两者都是可重入锁
-
可重入锁指的是在一个线程中可以多次获取同一把锁,比如:一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接执行调用的方法,而无需重新获得锁,两者都是同一个线程每进入一次,锁的计数器都自增1,所以要等到锁的计数器下降为0时才能释放锁
-
-
用法语法
-
synchronized是Java中的关键字,可以直接应用于代码或者方法块
-
ReentrantLock是具体类,实现了lock接口,需要调用lock、unlock方法实现上锁解锁
-
-
获取与释放锁的控制
-
synchronized 是隐式的加锁和解锁,锁不需要手动释放
-
ReentrantLock必须显示地调用 lock() 和 unlock() 方法来获取和释放锁
-
-
公平性选择
-
synchronized默认是非公平锁,即不保证线程获取锁的顺序与它们请求锁的顺序一致
-
ReentrantLock可以选择是否为公平锁,公平锁将按照线程请求锁的顺序来分配锁资源
-
-
可中断性
-
synchronized不支持中断正在等待获取锁的线程,一旦一个线程进入等待状态就无法响应中断请求
-
ReentrantLock支持中断等待锁的线程,可以通过
lockInterruptibly()
方法尝试获取锁,并可以响应中断请求
-