Java线程之Lock实现锁的管理
来源:互联网 发布:淘宝网店出售平台 编辑:程序博客网 时间:2024/06/05 04:37
1. 两个通用类
ReentrantLock类和ReentrantReadWriteLock类。
2. 作用与区别
- 都可以实现类似synchronized关键字的功能,通过lock()方法和unlock()方法实现锁的获取与释放。
- 不同点在于ReentrantLock具有完全互斥排他的效果,即同一时间只有一个线程在执行ReentrantLock.lock()方法后面的任务,不管执行的内容是否都需要同步执行。而ReentrantReadWriteLock有两个锁,一个是读操作相关的锁,也称为共享锁;另一个是写操作相关的锁,也叫排他锁。
- 读写锁的规则互斥规则为读锁之间不互斥,读锁与写锁互斥(先读后写或先写后读均互斥),写锁与写锁互斥。
3. 公平锁与非公平锁
锁Lock分为“公平锁”和“非公平锁”,公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即先来先得的FIFO先进先出顺序。而非公平锁就是一种获取锁的抢占机制,是随机获得锁的,和公平锁不一样的就是先来的不一定先得到锁,这个方式可能造成某些线程一直拿不到锁。
公平锁/非公平锁可以通过构造器ReentrantLock(boolean isFair)来创建,默认情况下,ReentrantLock类使用的是非公平锁。
4. Lock常用方法
- getHoldCount()
查询当前线程保持此锁定的个数,也就是调用lock方法的次数。 - getQueueLength()
返回正等待获取此锁定的线程估计数。 - getWaitQueueLength(Condition condition)
返回等待与此锁定相关的给定条件Condition的线程估计数。 - hasQueuedThread(Thread thread)
查询指定的线程是否正在等待获取此锁定。 - hasQueuedThreads()
查询是否有线程正在等待获取此锁定。 - hasWaiters(Condition condition)
查询是否有线程正在等待与此锁定有关的condition条件。 - isFair()
判断是不是公平锁 - isHeldByCurrentThread()
查询当前线程是否保持此锁定。 - isLocked()
查询此锁定是否由任意线程保持。 - lockInterruptibly()
如果当前线程未被中断,则获取锁定,如果已经被中断则出现异常。(如果用lock(),即使线程被中断,也不会出现异常,正常执行)。 - tryLock()
尝试获取锁,若获取成功,标记下是该线程获取到了锁,然后返回true;若获取失败,此时直接返回false。 - tryLock(long timeout, TimeUnit unit)
如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定。 - lock()、lockInterruptibly()、tryLock()之间的关系
- 使用lock()获取锁,若获取成功,标记下是该线程获取到了锁(用于锁重入),然后返回。若获取失败,这时跑一个for循环,循环中先将线程阻塞放入等待队列,当被调用signal()时线程被唤醒,这时进行锁竞争(因为默认使用的是非公平锁),如果此时获取到了锁那么就返回,如果没获取到那么再次放入等待队列,等待唤醒,如此循环。其间就算外部调用了interrupt(),循环也会继续走下去。一直到当前线程获取到了这个锁,此时才处理interrupt标志,若有,则执行 Thread.currentThread().interrupt(),结果如何取决于外层的处理。
- 和lock()相比,lockInterruptibly()只有略微的修改,for循环过程中,如果检测到interrupt标志为true,则立刻抛出InterruptedException异常,这时程序便通过异常直接返回到最外层了,由外层继续处理,因此使用lockInterruptibly()时必须捕捉异常。
- 使用tryLock()尝试获取锁,若获取成功,标记下是该线程获取到了锁,然后返回true;若获取失败,此时直接返回false,告诉外层没有获取到锁,之后的操作取决于外层。
5. ReentrantLock代码示例
synchronized方法实现
public class MyService { public void testMethod() { synchronized (this) { // 功能代码 } }}
Lock方法实现
public class MyService { private Lock lock = new ReentrantLock(); public void testMethod() { lock.lock(); // 功能代码 lock.unlock(); }}
以上两种实现方式的执行效果是一样的。
6. ReentrantReadWriteLock代码示例
读锁
public class Service { private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void read() { try { lock.readLock().lock(); // 业务代码 } finally { lock.readLock.unlock(); } }}
写锁
public class Service { private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); public void write() { try { lock.writeLock().lock(); // 业务代码 } finally { lock.writeLock.unlock(); } }}
7. 类Condition
- 作用:通过await()方法和signal()方法可以实现等待/通知的功能,类似于Object的wait()和notify()方法,不过使用Condition更灵活,如“选择性通知”。
- Object类中的wait()方法相当于Condition类中的await()方法。
- Object类中的wait(long timeout)方法相当于Condition类中的await(long time, TimeUnit unit)方法。
- Object类中的notify()方法相当于Condition类中的signal()方法。
- Object类中的notifyAll()方法相当于Condition类中的signalAll()方法。
- 创建方式:
Lock lock = new ReentrantLock();Condition condition = lock.newCondition();
- 注意事项:在condition.await()和condition.signal()方法调用之前需要调用lock.lock()代码获得同步监视器。
8. Condition常用方法
- awaitUninterruptibly()
类似await(),不过在等待过程中被中断时不抛中断异常。 - awaitUntil(Date deadLine)
类似await(),不过在等待时间到达后,如果可获取到锁,则自动唤醒。在等待时间到达前,也可以被其他线程唤醒。
阅读全文
0 0
- Java线程之Lock实现锁的管理
- java线程锁之lock
- java线程同步之Lock锁
- Java高级之Lock&Condition实现线程同步通信
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
- synchronized和LOCK的实现---Java之锁研究
- Lock实现线程的同步
- java线程Lock的wait
- java 线程七-Lock锁
- java--线程--锁-Lock/ReentrantReadWriteLock
- Java 多线程 (PART XVII) Lock (I) Lock实现线程同步
- 多线程 之 Lock 锁的实现原理
- java锁机制,LOCK的实现类
- Java线程之Read-Write Lock Pattern
- java多线程之Lock线程同步
- Java线程学习笔记之Lock
- java线程之线程同步与线程通信(Synchronized/Lock)
- Java中锁的应用之-Lock
- ==和equals
- jmeter循环控制器和结果的正则提取
- C语言的面向对象设计 —— 对 X264/FFMPEG 架构探讨——胜读十年书
- Linux 递归删除文件夹命令
- Junit(1)在Eclipse中使用JUnit4进行单元测试
- Java线程之Lock实现锁的管理
- Python基础教程--抽象,函数,参数,递归,作用域
- Java to Kotlin(java 与 Kotlin对比)
- VUE2.0学习笔记
- dubbo用户指南
- 封装-给继承自UIView的控件添加点击事件
- MOOC清华《程序设计基础》第3章:谁做的好事(循环枚举)
- ElasticSearch5.4.3 环境搭建 2017 (1.1-单节点模式/开发模式-添加到服务)
- PHP RSA2 签名算法