同一个线程获取锁之后,能再次重复加锁,这个锁就是可重入的。
锁的公平性获取锁的顺序与线程请求加锁的顺序一致,这个锁就是公平的。线程获取锁等待的时间越长优先获取锁。
公平锁比非公平锁的效率要低,在竞争很激烈时,会造成大量的让步式上下文切换。
公平锁为了控制加锁的顺序,锁一旦被加上之后,后续的线程都必须进入同步队列等待,通常自旋获取不到锁,进而线程阻塞等待,直到被唤醒之后才能获得锁。
非公平锁被加上之后,未入同步队列的线程有机会直接竞争到锁而不必进入同步队列阻塞等待。
锁的排他性同一时间如果只有一个线程能获取到锁,这个锁就是排他的。
| 锁 | 可重入性 | 公平性 | 排他性 | 响应中断 |
| synchronized | 可重入 | 非公平 | 排他 | 不响应 |
| ReentrantLock | 可重入 | 两种模式都支持 | 排他 | 中断模式支持 |
| ReentrantReadWriteLock | 可重入 | 两种模式都支持 | 读锁之间不排他 写锁排他 | 中断模式支持 |
大多数场景读比写多,在读比写多的场景下,读写锁比排它锁的并发性和吞吐量高。
ReentrantLock可重入锁ReentrantLock的类图
ReentrantReadWriteLock可重入读写锁AQS中state的高16位表示读锁状态;
AQS中state的低16位表示写锁状态。
通过位运算获取读锁、写锁的状态。
假设state的当前值为S
读锁状态 = S >>> 16 (无符号补0按位右移16位,高16移动到低16位,高16位补0)
写锁状态 = S & 0x0000FFFF (把高16位置为0)
当写锁状态 > 0时,写状态为线程获取写锁的次数,如果读状态大于0,当前线程获取到写锁后也获取了读锁,读状态就是获取读锁的次数。
当写锁状态 = 0时,读锁状态 > 0时,读锁被加上,读状态为读锁被获取的总次数。Java6之后将每个线程获取读锁次数记录在本线程的本地变量(ThreadLocal)中。
获取写锁成功时,执行CAS操作,写锁状态=S+1;释放写锁时,执行操作,写锁状态=S-1。
获取读锁成功时,执行CAS操作,读锁状态=S+0x00010000;释放读锁时,执行CAS操作,读锁状态=S-0x00010000。
LockSupport工具可以通过LockSupport工具完成对线程的阻塞和唤醒。
| 方法 |
| public static void park(Object blocker) |
| public static void parkNanos(Object blocker, long nanos) |
| public static void parkUntil(Object blocker, long deadline) |
| public static Object getBlocker(Thread t) |
| public static void park() |
| public static void parkNanos(long nanos) |
| public static void parkUntil(long deadline) |
| public static void unpark(Thread thread) |
当一个线程调用未指定等待时间的park()方法后,该线程阻塞等待。当这个线程被中断,或者被其他线程调用unpark方法,这个线程才会从park()方法返回。
当一个线程调用指定等待时间的park()方法后,该线程阻塞等待,等待时间为指定的时间。当这个线程被中断,或者被其他线程调用unpark方法,或者等待时间借宿,这个线程才会从park()方法返回。
Condition接口在多线程之间实现通知和等待模式的方式有两种:
(1)Java对象的监视器方法,java.lang.Object提供,包括wait(),wait(long timeout),notify()和notifyAll()。注意要结合synchronized关键字使用。
(2)Condition提供的监视器方法。注意要结合Lock锁使用。
AQS内部类ConditionObject实现了Condition接口,Condition的操作需要操作关联的锁,所以把ConditionObject放在AQS内部。ConditionObject包含一个FIFO的等待队列,在Condition对象上等待的线程会进入这个等待队列。
在Object的监视器模型中,一个对象拥有一个同步队列和一个等待队列。并发包的Lock(内部的AQS队列同步器)拥有一个同步队列和多个等待队列。
| 同步队列数 | 等待队列数 | |
| Object监视器模型 | 1个 | 1个 |
| 并发包的Lock监视器模型 | 1个 | 多个 |
《Java并发编程的艺术》 机械工业出版社 方腾飞 魏鹏 程晓明



