024 可重入锁

一 . 概述

  在JDK5之前,我们都需要使用synchronized来完成内置锁的实现同步效果,Synchronized的操作力度过大,因而出现了一个替代的产品ReentrantLock(可重入锁).


二 .可重入锁的基本使用

  在这里我们还是使用前面的计数操作完成演示.  

public class ReenTest {
    // 创建一个可重入锁
    private static Lock lock = new ReentrantLock();

    private int count = 0;

    private void add() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }

    }

    public static void main(String[] args) throws Exception {
        ReenTest test = new  ReenTest();
        Thread t1 = new Thread(()->{
            for(int x = 0; x< 10000 ;x++) {
                test.add();
            }
        } ) ;
        Thread t2 = new Thread(()->{
            for(int x = 0; x< 10000 ;x++) {
                test.add();
            }
        } );
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("最终的结果count:"+test.count);
    }
}

我们看到可重入锁的使用非常简单,核心方法一个是lock(),另外一个就是unlock()方法.

  注意 : 我们的unlock一定要放置在finally之中,保证锁一定是释放的,否则可能会出现死锁.


三 , 可重入锁实现的四个特点

[1]阻塞式

可重入锁一样是阻塞式的,也就是说,进入临界资源的线程只有一个.

[2]可重入性

这个比较简单了,名字就知道了.

[3]公平性

我们首先观察可重入锁的构造方法

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

这个构造函数指明锁是否是公平锁.,我们通过构造函数来指明.默认是非公平锁.

那么什么是公平和非公平呢?我们知道所有的线程被阻塞到AQS的队列之中,实际上这些线程也是有先来后到的.

所谓公平,就是保证这个先来后到.

所谓不公平,就是前一个线程完成之后,所有线程再次抢夺一个资源.


四 .总结

我们使用可重入锁基本能替代掉synchronized关键词,相比较而言,我们还能实现更加灵活的操作.

  缺点也是有的,我们需要使用大量的代码去控制lock的使用.

原文地址:https://www.cnblogs.com/trekxu/p/9005605.html