zoukankan      html  css  js  c++  java
  • ReentrantLock 相关学习笔记

    ReentrantLock 相关学习笔记

    标签(空格分隔): Java多线程


    Java接口Lock有三个实现类:ReentrantLock、ReentrantReadWriteLock.ReadLock和ReentrantReadWriteLock.WriteLock。Lock接口提供了比使用synchronized更广泛的锁操作。

    ReentrantLock是一个可重入的互斥锁。重入的含义是:当某个线程请求一个由其他线程持有的锁时,发出请求的线程就会被阻塞。但是如果某个线程试图获得一个已经由它自己持有的锁时,这个请求是会成功的。"重入"意味着获取锁的操作的粒度是"线程",而不是"调用"。重入的一种实现方式就是,为每个锁关联一个获取计数值和一个所有者线程。当计数值为0时,这个锁就被认为是没有被任何线程持有。当线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取到的计数值置为1.如果同一个线程再次获取这个锁,计数值将被递增,而当线程退出同步代码块时,技术器会相应地递减。当计数值为0时,这个锁将被释放。

    对于ReentrantLock锁将由最近成功获得锁,并且没有释放该锁的线程所拥有。当锁没有被另外一个线程所拥有时,调用lock的线程将会成功获取该锁并返回。如果当前线程已经拥有该锁,此方法将立即返回。

    ReentrantLock基础API

    1. lock() 获取锁
      加锁,如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为1。
      如果当前线程之前已经获取到了该锁,则将保持计数加1,并且该方法立即返回。
      如果该锁已经被另一个线程保持,则该线程不可被调度(即当前线程处于阻塞状态)直到该线程获取到锁,并且在获取到锁后,将保持计数设置为1。

    2. unlock释放锁
      试图释放锁。如果当前线程是此锁所有者,则将保持计数减1。如果保持计数器现在为0,则释放该属锁。如果当前线程不是此锁的持有者,则抛出IllegalMonitorStateException。

    private Lock lock = new ReentrantLock() ;
    public void await() {
        try {
             lock.lock();//加锁
        }  finally {
            lock.unlock();//释放锁
        }
    }
    
    1. trylock()
    • 仅在调用时锁未被另一个线程保持的情况下,才获取锁。

    • 如果该锁没有被另一个线程保持,并且立即返回 true 值,则将锁的保持计数设置为 1。即使已将此锁设置为使用公平排序策略,但是调用 tryLock() 仍将 立即获取锁(如果有可用的),而不管其他线程当前是否正在等待该锁。在某些情况下,此“闯入”行为可能很有用,即使它会打破公平性也如此。如果希望遵守此锁的公平设置,则使用 tryLock(0, TimeUnit.SECONDS) ,它几乎是等效的(也检测中断)。

    • 如果当前线程已经保持此锁,则将保持计数加 1,该方法将返回 true。

    • 如果锁被另一个线程保持,则此方法将立即返回 false 值。

    1. tryLock(long timeout, TimeUnit unit)
    • 如果锁在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁。

    • 为了使用公平的排序策略,如果其他线程已经获取此锁,并且还有其他线程都在等待该锁,则立刻不会获取一个可用的锁,而公平的和其他线程进行等待锁分配。这与trylock方法相反。如果想使用一个允许闯入公平锁的定时tryLock,那么可以将定时形式和不定时形式组合在一起使用:

    if(lock.tryLock() || lock.tryLock(timeout,uniy)) {
    //.....
    }
    
    1. lockInterruptibly
      如果当前线程未被中断,则获取锁。
    • 如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为1。
    • 如果该线程已经保持此锁,则将保持计数加1,并且该方法立即返回。
    • 如果该锁已经被其他线程保持,则等待;等待过程中,如果被其他线程打算,则抛出InterrupterException,并且中断该线程。
    • 在具体业务里,因为此方法是一个显示中断点,所以要优先考虑响应中断,而不是响应锁的普通获取或重入获取。

    总结

    • lock --> 无限锁 调用后一直阻塞直到获得锁。
    • tryLock --> 拿到锁就返回true,不然就返回false;带有时间限制的tryLock(),拿不到锁,就等待一段时间,超时返回false。与while配合,可以实现轮询锁。
    • lockInterruptibly --> 调用后如果没有获取到锁会一直阻塞,阻塞过程中会接受中断信号。

    参考原文地址

    1. Java中Lock,tryLock,lockInterruptibly有什么区别?
  • 相关阅读:
    第四章JAVA EE基础知识
    第二章代码审计环境搭建
    第三章代码审计辅助工具简介
    python json.dumps 中文需要注意的事项
    multiprocessing 使用实践
    Python中*args和**kwargs的使用实践
    python 继承学习记录
    关于vue-element-admin启动项目遇到的一些问题
    @RequestParam
    前端菜单点击切换样式,菜单控制iframe
  • 原文地址:https://www.cnblogs.com/boothsun/p/6556297.html
Copyright © 2011-2022 走看看