1、ReentrantLock介绍

2、ReentrantLock的方法

3、ReentrantLock的使用

好了,开始正文

1、ReentrantLock介绍

1) 在Java5.0以前,协调对共享对象的访问可以使用的机制只有synchronized和volatile,也称内置锁。
在Java5.0之后呢,出现了一种新的机制:ReentrantLock,也称外置锁。
这个机制的出现并不是想要替代内置锁,而是在内置加锁机制不适用时,作为一种可选择的高级功能。
怎么就高级了呢?
ReentrantLock,它实现了一个Lock接口,这个Lock接口中定义了一组抽象的加锁操作。
而Lock提供了一种无条件的、可轮询的、定时的以及可中断的锁获取操作,这就是它优于synchronized的地方。
2)synchronized是一个关键字,修饰方法和代码块的时候,它范围就在那对花括号里,其它的事情也不需要操心,即是Java内置的锁;
ReentrantLock是一个类,加锁方式的实现,是要手动加锁跟手动释放锁,故被称为外置锁。

2、ReentrantLock的方法

ReentrantLock实现了Lock接口,
那这个无条件的、可轮询的、定时的以及可中断的锁获取操作由Lock接口的方法可体现
1)void lock();//Acquires the lock(源码释义),获取锁
2)void lockInterruptibly() throws InterruptedException; //Acquires the lock unless the current thread is {@linkplain Thread#interrupt interrupted}.
得到这个锁,除非当前线程被打断了。
这一点就是可中断的锁操作,当前的线程若是被打断了,就立即返回;synchronized是没有这种操作的。
3)boolean tryLock(); //Acquires the lock only if it is free at the time of invocation
尝试获取锁,且获取到就返回true,否则返回false。
4)boolean tryLock(long time, TimeUnit unit) throws InterruptedException; //Acquires the lock if it is free within the given waiting time and the current thread has not been {@linkplain Thread#interrupt interrupted}.
如果在给定的时间锁是空闲的并且没有被打断,就去获取锁。

这个方法中两个参数:long time->给定一个时间,它的单位由后面的TimeUnit unit决定。
补充一下,这个TimeUnit是一个枚举类,最常使用的地方是是代替了Thread.sleep(毫秒)方法,替换成了TimeUnit.时间单位.sleep(数值),比如,TimeUnit.SECONDS.sleep(2),睡上它两秒。

3)、4)两点就是可轮询的、定时的所获取操作。
相比较而言,synchronized就不能人为的设置这些东西。
5void unlock();//Releases the lock,释放锁,这一步是要手动添加在代码中的,不添加就会出大问题。
以上,1)、2)、3)、4)就是进行加锁;5)当然是释放锁

3、ReentrantLock的使用

首先看一下synchronized的使用;
1)同步代码块

synchronized public static void fun1() {
        //do something
    }

2)同步方法

public static void fun2() {
        synchronized (Object.class) {
            //do something
        }
    }

再比较ReentrantLock

public static void fun3() {
        Lock lock = new ReentrantLock();//获取ReentrantLock对象

        try {
            lock.lock();
            //or lock.lockInterruptibly();
            //or lock.tryLock();
            //or lock.tryLock(long time, TimeUnit unit);
            //->lock.tryLock(2, TimeUnit.SECONDS);//睡2秒获取不到锁就放弃

            //do something
        }  finally {
            lock.unlock();
        }
    }