java---ReentrantLock

简介: ReentrantLock介绍java多线程中可以使用synchronized关键字来实现线程间同步互斥,但在jdk1.5中新增加了ReentrantLock类也能实现同样的效果。

ReentrantLock介绍

java多线程中可以使用synchronized关键字来实现线程间同步互斥,但在jdk1.5中新增加了ReentrantLock类也能实现同样的效果。

ReentrantLock:表示重入锁,它是唯一一个实现了Lock接口的类。重入锁指的是 线程在获得锁之后,再次获取该锁不需要阻塞,而是直接关联一次计数器增加重入次;

Lock常用方法

网络异常,图片无法展示
|

ReentrantLock.lock() 这个是reentrantLock获取锁的入口

public void lock() {
        sync.lock();
    }

网络异常,图片无法展示
|

sync实际上是一个抽象的静态内部类,它继承了AQS来实现重入锁的逻辑,我们前面说过AQS是一个同步队列,它能够实现线程的阻塞以及唤醒,但它并不具备 业务功能,所以在不同的同步场景中,会继承AQS来实现对应场景的功能 Sync有两个具体的实现类,

什么是AQS?

AQS即AbstractQueuedSynchronizer,是一个用于构建锁和同步器的框架。它能降低构建锁和同步器的工作量,还可以避免处理多个位置上发生的竞争问题。在基于AQS构建的同步器中,只可能在一个时刻发生阻塞,从而降低上下文切换的开销,并提高吞吐量

AQS支持独占锁(exclusive)和共享锁(share)两种模式。

  • 独占锁:只能被一个线程获取到(Reentrantlock)
  • 共享锁:可以被多个线程同时获取(CountDownLatch,ReadWriteLock).

分别是:

NofairSync:非公平锁,可以存在抢占锁的功能,也就是说不管当前队列上是否存在其他 线程等待,新线程都有机会抢占锁

FailSync:公平锁,所有线程严格按照FIFO来获取锁

公平锁示例

谁等的时间最长,谁就先获取锁

public class ReentrantLockTest {
    static Lock lock = new ReentrantLock(true);
    public static void main(String[] args) throws InterruptedException {
        for(int i=0;i<5;i++){
            new Thread(new ThreadDemo(i)).start();
        }
    }
    static class ThreadDemo implements Runnable {
        Integer id;
        public ThreadDemo(Integer id) {
            this.id = id;
        }
        @Override
      public void run() {
            try {
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for(int i=0;i<2;i++){
                lock.lock();
                System.out.println("获得锁的线程:"+id);
                lock.unlock();
            }
        }
    }
}

非公平锁示例

非公平锁那就随机的获取,谁运气好,cpu时间片轮到哪个线程,哪个线程就能获取锁

static Lock lock = new ReentrantLock(false);//参数为false,当然我们也可以不写,默认就是false

ReentrantLock和synchronized对比

(1)synchronized是独占锁,加锁和解锁的过程自动进行,易于操作,但不够灵活。ReentrantLock也是独占锁,加锁和解锁的过程需要手动进行,不易操作,但非常灵活。

(2)synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;ReentrantLock也可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。

(3)synchronized不可响应中断,一个线程获取不到锁就一直等着;ReentrantLock可以相应中断。

总结

ReentrantLock是一种可重入的,可实现公平性的互斥锁,它的设计基于AQS框架,可重入和公平性的实现逻辑都不难理解,每重入一次,state就加1,当然在释放的时候,也得一层一层释放。至于公平性,在尝试获取锁的时候多了一个判断:是否有比自己申请早的线程在同步队列中等待,若有,去等待;若没有,才允许去抢占。


目录
打赏
0
0
0
0
4
分享
相关文章
java202303java学习笔记第三十八天死锁2
java202303java学习笔记第三十八天死锁2
54 0
java202303java学习笔记第三十八天死锁
java202303java学习笔记第三十八天死锁
55 0
java202303java学习笔记第三十八天插入线程
java202303java学习笔记第三十八天插入线程
42 0
java202303java学习笔记第三十一天ArrayList源码分析2
java202303java学习笔记第三十一天ArrayList源码分析2
60 0
java202303java学习笔记第三十一天红黑树4
java202303java学习笔记第三十一天红黑树4
59 0
java202303java学习笔记第三十一天红黑树5-1
java202303java学习笔记第三十一天红黑树5
86 0
java202303java学习笔记第三十一天红黑树2
java202303java学习笔记第三十一天红黑树2
59 0
java202303java学习笔记第三十一天红黑树1
java202303java学习笔记第三十一天红黑树1
53 0
java202303java学习笔记第三十一天红黑树3
java202303java学习笔记第三十一天红黑树3
69 0
java202303java学习笔记第三十一天红黑树5-2
java202303java学习笔记第三十一天红黑树5
66 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等