ReentrantLock 可重入锁

ReentrantLock 可重入锁


ReentrantLock,可重入锁,是一种递归无阻塞的同步机制。它可以等同于synchronized的使用,但是ReentrantLock提供了比synchronized更强大、灵活的锁机制,可以减少死锁发生的概率。

公平锁与非公平锁

ReentrantLock还提供了公平锁也非公平锁的选择,构造方法接受一个可选的公平参数(默认非公平锁),当设置为true时,表示公平锁,否则为非公平锁。

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

公平锁与非公平锁的区别在于公平锁的锁获取是有顺序的。但是公平锁的效率往往没有非公平锁的效率高,在许多线程访问的情况下,公平锁表现出较低的吞吐量。

ReentrantLock与synchronized的区别

  1. 与synchronized相比,ReentrantLock提供了更多,更加全面的功能,具备更强的扩展性。例如:时间锁等候,可中断锁等候,锁投票。
  2. ReentrantLock还提供了条件Condition,对线程的等待、唤醒操作更加详细和灵活,所以在多个条件变量和高度竞争锁的地方,ReentrantLock更加适合(以后会阐述Condition)。
  3. ReentrantLock提供了可轮询的锁请求。它会尝试着去获取锁,如果成功则继续,否则可以等到下次运行时处理,而synchronized则一旦进入锁请求要么成功要么阻塞,所以相比synchronized而言,ReentrantLock会不容易产生死锁些。
  4. ReentrantLock支持更加灵活的同步代码块,但是使用synchronized时,只能在同一个synchronized块结构中获取和释放。注:ReentrantLock的锁释放一定要在finally中处理,否则可能会产生严重的后果。
  5. ReentrantLock支持中断处理,且性能较synchronized会好些。

可使用的方法

//如果该锁没有被其他线程获得,则获得当前锁;如该线程已经获得当前锁,
则当前锁的count加1(即可重入);否则阻塞该线程,直到当前锁可被获得
public void lock() {
    sync.lock();
}
//尝试获取锁直到该线程被中断
public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }
//只有在当前锁未被别的线程获取时才获取锁,返回true, 否则返回false。
public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }
//在规定时间内且该线程未被中断,尝试获取锁,获得成功则返回true,否则返回false。
public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }
//释放锁。如果该线程是锁的持有者,则count减1,直到count为0,锁成功释放。
若该线程不是锁的持有者,则抛出异常。
public void unlock() {
        sync.release(1);
    }
//返回当前锁的Condition实例,这个后面会讲
public Condition newCondition() {
        return sync.newCondition();
    }
//返回当前线程持有锁的数量
public int getHoldCount() {
        return sync.getHoldCount();
    }
//判断该锁是否被该线程持有
public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }
······还有几个就不写了

参考资料:

http://cmsblogs.com/?p=2210

posted @ 2018-09-25 20:05  一把水果刀  阅读(395)  评论(0编辑  收藏  举报