ReentrantLock理解

来源:互联网 发布:游戏程序员 职业规划 编辑:程序博客网 时间:2024/05/24 04:42
互斥锁:线程会从sleep(加锁)——>running(解锁),过程中有上下文的切换,cpu的抢占,信号的发送等开销。
自旋锁:线程一直是running(加锁——>解锁),死循环检测锁的标志位,机制不复杂。

java.util.concurrent.locks包提供了锁和等待条件的接口和类

互斥锁--Lock接口及其实现类ReentrantLock,所谓互斥锁, 指的是一次最多只能有一个线程持有的锁.
Lock lock = new ReentrantLock();  
// 获取锁  
lock.lock();  
    try {  
        // access the resource protected by this lock  
    } finally {  
        // 释放锁  
        lock.unlock();  
    }

条件--Condition
void await(): 调用Condition对象的await()方法将导致当前线程被挂起, 并释放该Condition对象所绑定的锁.
 Condition对象只能通过Lock类的newCondition()方法获取, 因此一个Condition对象必然有一个与其绑定的Lock锁. 调用Condition对象的await()方法的前提是: 当前线程必须持有与该Condition对象绑定的锁, 否则程序可能抛出异常.
void signal(): 唤醒一个在该Condition对象上挂起的线程. 如果存在多个线程等待这个Condition对象的唤醒, 则随机选择一个. 线程被唤醒之前, 必须重新获取到锁(与该Condition对象绑定的Lock对象).
void signalAll(): 唤醒所有在该Condition对象上挂起的线程. 所有被唤醒的线程将竞争与该Condition对象绑定的锁, 只有获取到锁的线程才能恢复到运行状态.

读写锁--ReadWriteLock接口及其实现类ReentrantReadWriteLock
ReentrantReadWriteLock中定义了2个内部类, ReentrantReadWriteLock.ReadLock和ReentrantReadWriteLock.WriteLock, 分别用来代表读取锁和写入锁. ReentrantReadWriteLock对象提供了readLock()和writeLock()方法, 用于获取读取锁和写入锁.
1.读取锁允许多个reader线程同时持有, 而写入锁最多只能有一个writter线程持有.
  lock.readLock().lock();或者lock.writeLock().lock();  
2.读写锁的使用场合: 读取共享数据的频率远大于修改共享数据的频率. 在上述场合下, 使用读写锁控制共享资源的访问, 可以提高并发性能.
3.如果一个线程已经持有了写入锁, 则可以再持有读写锁. 相反, 如果一个线程已经持有了读取锁, 则在释放该读取锁之前, 不能再持有写入锁.
4.可以调用写入锁的newCondition()方法获取与该写入锁绑定的Condition对象, 此时与普通的互斥锁并没有什么区别. 但是调用读取锁的newCondition()方法将抛出异常.

    

原创粉丝点击