行业资讯 2025年08月6日
0 收藏 0 点赞 342 浏览 3293 个字
摘要 :

文章目录 Java lock锁的是什么? Lock接口基本的方法 多线程lock的用法-ReentrantLock的基本使用 tryLock() tryLock(long time,TimeUnit unit) 锁的可重入性 lockInter……




  • Java lock锁的是什么?
  • Lock接口基本的方法
  • 多线程lock的用法-ReentrantLock的基本使用
    • tryLock()
    • tryLock(long time,TimeUnit unit)
  • 锁的可重入性
  • lockInterruptibly()方法
  • newCondition()方法
  •  总结

Java lock锁的是什么?

在JDK5中新增了 java.util.concurrent.locks 包下的Lock锁接口,有ReentrantLock实现类等。ReentrantLock锁称为可重入锁。

Lock 实现提供了比 synchronized 关键字更广泛的锁操作,它能以更优雅的方式处理线程同步问题。Lock提供了比synchronized更多的功能。

Lock接口基本的方法

方法名称 描述
void lock() 获得锁。如果锁已经被其他线程获取,则进行等待
boolean tryLock() 只有在调用时才可以获得锁。如果可用,则获取锁定,并立即返回值为true;如果锁不可用,则此方法将立即返回值为false 。
boolean tryLock(long time, TimeUnit unit) 超时获取锁,当前线程在一下三种情况下会返回: 1. 当前线程在超时时间内获得了锁;2.当前线程在超时时间内被中断;3.超时时间结束,返回false.
void lockInterruptibly() 获取锁,如果可用并立即返回。如果锁不可用,那么等待,和 tryLock(long time, TimeUnit unit) 方法不同的是等待时间无限长,但是在等待中可以中断当前线程(响应中断)。
Condition newCondition() 获取等待通知组件,该组件和当前的锁绑定,当前线程只有获得了锁,才能调用该组件的wait()方法,而调用后,当前线程将释放锁。
void unlock() 释放锁。

多线程lock的用法-ReentrantLock的基本使用

我们先来讲下列2种方法实现显示锁的范式书写方法:

  • lock();
  • unlock();
/**
 * 显示锁的范式
 */
public class LockDemo {
  // 创建
  private Lock lock = new ReentrantLock();
  private int count = 0;
  /**
   * 利用显示锁进行count的累加
   */
  public void increamentByLock() {
    // 显示锁的范式
    // 开启锁;
    lock.lock();
    try {
      count++;
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      // 一定要在finally中将锁进行释放,防止出现异常后锁不释放造成的线程阻塞
      lock.unlock();
    }
    System.out.println(count);
  }
  /**
   * 利用synchronized进行count的累加
   */
  public synchronized void increamentBySyn() {
    count++;
    System.out.println(count);
  }
}

一般将lock.lock()写在try外面,不建议写try里面,lock.unlock()写在finally中。不管在哪里的代码,只要使用了同一个Lock,都可以进行线程同步。

通过以上我们可以看到:

1、显示锁有其书写范式,一定要遵从该范式进行书写,避免出现异常造成线程阻塞。

2、synchronized内置锁要比显示锁书写要更加简洁。

关于《Lock和Synchronized的具体区别》可直接去查看。

tryLock()

  • tryLock()用来尝试获取锁,如果当前线程没有被其他线程占用,则获取成功,则返回true,否则返回false,代表获取锁失败
  • 相比上面的lock(),他可以返回一个值,让我们知道是否成功获取到锁;进而决定后续程序的行为
  • 它会立刻返回,即便在拿不到锁时,不会一直等待

一般情况下通过tryLock来获取锁时是这样使用的:

Lock lock = ...;
if(lock.tryLock()) {
     try{
         //处理任务
     }catch(Exception ex){
        
     }finally{
         lock.unlock();   //释放锁
     }
}else {
    //如果不能获取锁,则直接做其他事情
}

tryLock(long time,TimeUnit unit)

可以设定超时时间的尝试获取锁,一段时间内等待锁,超时就放弃。

锁的可重入性

锁的可重入性是指,当一个线程获得一个对象锁后,再次请求该对象锁时,可以再次获得该对象的锁。非可重入锁就是最常见的锁,一旦锁被使用,如果没有释放,就不能再使用这个锁了。

如果锁具备可重入性,则称作为可重入锁。像synchronized和 ReentrantLock都是可重入锁,可重入性实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。

举个简单的例子,当一 个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法 method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。

以下代码可以顺利运行下去,代表synchronized里面的锁是具有可重入性的:

public class Test01 {

    public synchronized void sm1() {
        System.out.println(\"同步方法1\");
        sm2();
    }

    public synchronized void sm2() {
        System.out.println(\"同步方法2\");
        sm3();
    }

    public synchronized void sm3() {;
        System.out.println(\"同步方法3\");
    }

    public static void main(String[] args) {
        Test01 obj = new Test01();
        new Thread(new Runnable() {
            @Override
            public void run() {
                obj.sm1();
            }
        }).start();
    }
}

lockInterruptibly()方法

如果在获取锁的过程中,线程的中断标志位为true,则获取锁失败,且立即报InterruptedException异常,并将中断标志位的值置为false。

对于synchronized内部锁来说,如果一个线程在等待锁,只有两个结果。要么线程获得锁继续执行,要么就保持。

对于Reentrant Lock可重入锁来说,提供了另外一种可能,在等待锁的过程中,程序可以根据需要取消对锁的请求。

由于lockInterruptibly()的声明中抛出了异常,所以lock.lockInterruptibly()必须放在try块中或者在调用lockInterruptibly()的方法外声明抛出InterruptedException

public  void  method()  throws  InterruptedException {
     lock.lockInterruptibly();
     try  {  
      //.....

     } finally  {
         lock.unlock();
     }  
}

newCondition()方法

synchronized与wait()、notify()这两个方法一起使用可以实现等待/通知模式,Lock锁的newCondition()方法返回Condition对象,也可以实现等待/通知模式

使用notify()通知后,JVM会随机唤醒某个等待的线程,使用Condition类可以进行选择性地通知某和线程。

Condition比较常用的两个方法:await()、singal()。注意,在调用这两个方法前,需要线程持有相关的Lock锁。调用await()后,线程会释放这个锁,调用signal()后,会从当前Condition对象的等待序列中唤醒一个线程。

后面我们会详解该方法,请参考《Java Lock锁Condition接口和newCondition()方法》

 总结

以上就是Java多线程:Lock显示锁详解,我们主要讲了Lock接口的使用方式,

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/9704.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号