Java_并发线程_Lock、ReadWriteLock
来源:互联网 发布:mac lnmp一键安装包 编辑:程序博客网 时间:2024/05/17 22:50
1.Lock
ReentrantLock是Lock接口的实现类,使用Lock应该接合线程来使用。如果lock锁没有被其它的线程占用,则当前线程可以立即获得lock锁。同一个线程可在lock锁未释放之前,调用lock多次,使用getHoldCount()得到当前线程lock锁的次数。isHeldByCurrentThread()则判断当前线程是否拥有lock锁。
(1).使用格式
一定要在finally中调用lock.unlock()解锁,防止死锁。Lock l = ...;l.lock();try {// access the resource protected by this lockfinally {l.unlock();}}
(2).常用方法
1).void lock();
尝试获得lock锁,如果锁被别的线程持有,则当前线程不在执行,也不能被调度,直到拿到锁为止;
2).void lockInterruptibly() throws InterruptedException
尝试获取锁,如果锁可以获取,那么立刻返回。如果无非获取锁,那么线程停止执行,并且不能被再调度,直到当前线程被interrupt,则抛出异常;
3).boolean tryLock()
尝试获得锁,如果成功那么锁住对象然后返回true,否则返回false,这个方法会立即返回;
4).boolean tryLock(long time, TimeUnit unit) throws InterruptedException
tryLock类似,等待最大时间内试图获得锁;
5).unlock()
释放锁,减一
6).newCondition()
参考Java_并发线程_Condition一文
(3).与synchronized的区别
synchronized锁的释放是语言内置的,不会出现忘记释放锁的情况,另外由于是语言内置的支持,调试是能很快知道锁被哪个线程持有,它加锁的次数。而Lock只是一个普通的类,所以调试器并不知道这个锁的任何信息,它只是一个普通的对象(当然你可以仔细观察每个线程的stack frame来看它在等待锁),但是Lock更加的灵活具有扩展性。
所以建议:如果只是为了实现互斥,那么使用synchronized,如果想用Lock附加的功能,那么才使用Lock。
2.ReadWriteLock
ReentrantReadWriteLock是ReadWriteLock接口的实现类,接合线程使用。
(1).读锁和写锁条件
1).不同一线程
读锁不互斥,读锁与写锁互斥,写锁与写锁互斥。
2).同一线程
读锁可以获得多次getReadHoldCount(),写锁可以获得多次getWriteHoldCount;
读锁下不能获得写锁,但是写锁下可以提前获得读锁。
(2).格式
class CachedData {Object data;volatile boolean cacheValid;final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();void processCachedData() {rwl.readLock().lock();if (!cacheValid) {// Must release read lock before acquiring write lockrwl.readLock().unlock();rwl.writeLock().lock();try {// Recheck state because another thread might have// acquired write lock and changed state before we did.if (!cacheValid) {// data = ...cacheValid = true;// Downgrade by acquiring read lock before releasing// write lockrwl.readLock().lock();}} finally {rwl.writeLock().unlock(); // Unlock write, still hold read}}try {// use(data);} finally {rwl.readLock().unlock();}}}
(3).使用注意
读锁是排写锁操作的,读锁不排读锁操作,多个读锁可以并发不阻塞。即在读锁获取后和读锁释放之前,写锁并不能被任何线程获得,
多个读锁同时作用期间,试图获取写锁的线程都处于等待状态,当最后一个读锁释放后,试图获取写锁的线程才有机会获取写锁。
写锁是排写锁、排读锁操作的。当一个线程获取到写锁之后,其他试图获取写锁和试图获取读锁的线程都处于等待状态,直到写锁被释放。
写锁是可以获得读锁的,即:
rwl.writeLock().lock();//在写锁状态中,可以获取读锁rwl.readLock().lock();rwl.writeLock().unlock();读锁是不能够获得写锁的,如果要加写锁,本线程必须释放所持有的读锁,即:rwl.readLock().lock();//......//必须释放掉读锁,才能够加写锁rwl.readLock().unlock();rwl.writeLock().lock();
- Java_并发线程_Lock、ReadWriteLock
- Java_并发线程_CompletionService
- Java_并发线程_Condition
- 4、线程安全_Lock
- Java多线程/并发06、线程锁Lock与ReadWriteLock
- Java_并发线程_Future、FutureTask、Callable
- Java_并发线程_Semaphore、CountDownLatch、CyclicBarrier、Exchanger
- Java_并发线程_Future、FutureTask、Callable
- Java并发ReadWriteLock接口
- (java多线程并发)控制并发线程数的Semaphore、ScheduledThreadPoolExcutor、BlockingQueue、ReadWriteLock
- JAVA_并发
- 线程ReadWriteLock 读写锁
- 线程之ReadWriteLock用法
- java并发编程(9)--java线程锁技术Lock&ReadWriteLock
- Java线程总结(八):并发包------读写锁ReadWriteLock的简单例子详细理解
- Java_线程
- JAVA_线程
- Java_线程
- cocos2dx三种定时器的使用以及停止schedule,scheduleUpdate,scheduleOnce
- C++ cout 输出顺序
- Java操作文件
- 解决ScrollView嵌套ListView问题
- 基于Android设备的Kali Linux渗透测试教程第1章渗透测试
- Java_并发线程_Lock、ReadWriteLock
- 数据结构之无向图邻接表DFS之查询遍历关节点(参考整理严蔚敏数据结构)
- 第九周项目五程序填充(3)
- 第9周项目6辨别小偷
- Mina框架项目运用
- Spring mvc详解
- bzoj 2740: 串
- 第九周项目5(3)
- Android星级滑块