ReentrantLock 与 synchronized对比

ReentrantLock 与 synchronized对比

最近有在阅读Java并发编程实战这本书,又看到了ReentrantLock和synchronized的对比,发现自己以前对于RenntrantLock的理解很片面,特此做一番总结,如果有总结不到位的,欢迎指出

java.util.concurrent.locks 
接口 Lock

所有已知实现类:
ReentrantLockReentrantReadWriteLock.ReadLockReentrantReadWriteLock.WriteLock

为什么需要Lock?

java.util.concurrent.locks 
接口 Lock

所有已知实现类:
ReentrantLockReentrantReadWriteLock.ReadLockReentrantReadWriteLock.WriteLock

Lock提供了一种如条件的、可轮训的、定时的以及可以终端的获取锁的操作,所有的加锁方式和解锁方式都是显式的。

public class Lock {
    private boolean locked = false;

    public Lock() {
    }

    public final synchronized void lock() throws InterruptedException {
        while(this.locked) {
            this.wait();
        }

        this.locked = true;
    }

    public final synchronized void unlock() {
        this.locked = false;
        this.notifyAll();
    }
}

 Lock是JAVA5.0出现的,它的出现并不是为了替代synchronized,而是在synchronized不适用的时候使用。

那么synchronized有什么局限性呢?

  • 无法中断一个正在获取锁的线程

当一个线程想获取已经被其他线程持有的锁时,就会发生堵塞,假设已经持有锁的线程一直不释放锁,那么线程就会一直等待下去。

  •  无法指定线程执行时间

比如,想要A线程执行某个操作,该操作在5分钟之内没有完成,就返回失败,5分钟之内完成就返回成功。对于synchronized内置锁是做不到的,而ReentrantLock是可以做到的。

相同点:

  • 独占锁: 一次只允许一个线程访问
  • 可重入锁: 一个线程可重复获得自己已获得锁,不会发生死锁。简单来说,递归的时候不会发生死锁

不同点:

  • Lock不是java内置的,synchronized是JVM内置的,因此是内置特性。
  • 释放锁的方式:
    • Lock 必须要在finally中手动释放锁
    • synchronized 会根据锁区域代码自动执行完毕,或者发生异常,JVM会自动释放锁

  

ReentrantLock的使用:

基本使用 

Lock lock = new ReentrantLock();
        lock.lock();
        try {
            //....
        } finally {
            lock.unlock();
        }

       

猜你喜欢

转载自www.cnblogs.com/amberbar/p/10296946.html