java--Lock锁

Java:多线程中的Lock锁(未完待续) 在Java中,Lock是一个接口,它提供了比synchronized关键字更高级的线程同步机制。使用Lock接口可以创建更复杂和灵活的同步结构。Lock接口的常用实现类有ReentrantLock和ReentrantReadWriteLock,它们提供了可重入的互斥锁和读写锁。在需要进行同步的代码块中,通过调用`lock()`方法来获取锁。 阅读详情

1.概述

锁是一种工具,用于控制对共享资源的访问

Lock和synchronized,这两个是最常见的锁,它们都可以达到线程安全的目的,但是在使用上和功能上又有较大的不同。

Lock并不是用来代替synchronized的,而是当使用synchronized不合适或不足以满足要求的时候,来提供高级功能的。

Lock接口最常见的实现类,是ReentrantLook

通常情况下,Lock只允许一个线程来访问这个共享资源,不过有时候,一些特殊的实现也可允许并发访问。比如,ReadWriteLock里面的ReadLock。

  • 为什么synchronized不够用

1.效率低:所得释放情况少,试图获得锁的时候不能设定超时,不能中断一个正在试图获得锁的线程

2.不够灵活:枷锁和释放锁时机单一,每个所仅有单一的条件某个对象,可能是不够的。

2Lock锁的主要方法介绍

  • 在lock声明了四个方法来获取锁
  • lock(),tryLock(),tryLock(long time,TimeUnit unit)和LockInterruptibly()

3lock()

lock()就是最普通的获取锁。如果锁已被其他线程获取,则进行等待

Lock()不会像synchronized一样在异常时自动释放锁

因此最佳实践是,在finally中释放锁,以保证发生异常时锁一定被释放

package cn.butool.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Lock()不会像synchronized一样在异常时自动释放锁
 * 因此最佳实践是,在finally中释放锁,以保证发生异常时锁一定被释放
 */
public class MustUnLock {
    private static Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        // 加锁
        lock.lock();
        try{
            //获取本锁,保护的资源
            System.out.println(Thread.currentThread().getName()+"开始执行任务");
        }finally {
            // 释放锁
            lock.unlock();
        }
    }
}

 4tryLock()、tryLock(long time,TimeUnit unit)

  1. lock()方法不能被中断,一旦陷入死锁,这会带来很大的隐患lock()就会陷入永久等待 ;
  2. tryLock()用来尝试获取锁,如果当前锁没有被其他线程占用,则获取成功,则返回true,否则返回false,代表获取锁失败。
  3. 该方法会立即返回,即便在拿不到锁时不会一直在那等
  4. tryLock(long time,TimeUnit unit)超时就放弃

5用tryLock来避免死锁

5.1代码

package cn.butool.lock;

import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 用TryLock来避免死锁
 */
public class TryLockDeadLock implements Runnable{

    public static void main(String[] args) {
        TryLockDeadLock r1 = new TryLockDeadLock();
        TryLockDeadLock r2 = new TryLockDeadLock();
        r1.flag=1;
        r2.flag=0;
        new Thread(r1).start();
        new Thread(r2).start();
    }
    int flag =1;
    static Lock locl1 = new ReentrantLock();
    static Lock locl2 = new ReentrantLock();
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(flag ==1){
                try {
                    if(locl1.tryLock(800, TimeUnit.MILLISECONDS)){
                        try {
                            System.out.println("线程1获取到了锁1");
                            Thread.sleep(new Random().nextInt(1000));

                            if(locl2.tryLock(800, TimeUnit.MILLISECONDS)){
                                try{
                                    System.out.println("线程1获取到了锁2");
                                    System.out.println("线程1获取到了2把锁");
                                    break;
                                }finally {
                                    locl2.unlock();
                                }
                            }else{
                                System.out.println("线程1获取锁2失败,已重试");
                            }

                        }finally {
                            locl1.unlock();
                            Thread.sleep(new Random().nextInt(1000));
                        }
                    }else{
                        System.out.println("线程1获取锁1失败,已重试");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if(flag ==0){
                try {
                    if(locl2.tryLock(3000, TimeUnit.MILLISECONDS)){
                        try {
                            System.out.println("线程2获取到了锁2");
                            Thread.sleep(new Random().nextInt(1000));

                            if(locl1.tryLock(800, TimeUnit.MILLISECONDS)){
                                try{
                                    System.out.println("线程2获取到了锁1");
                                    System.out.println("线程2获取到了2把锁");
                                    break;
                                }finally {
                                    locl1.unlock();
                                }
                            }else{
                                System.out.println("线程2获取锁1失败,已重试");
                            }

                        }finally {
                            locl2.unlock();
                            Thread.sleep(new Random().nextInt(1000));
                        }
                    }else{
                        System.out.println("线程2获取锁1失败,已重试");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

5.2打印

线程1获取到了锁1
线程2获取到了锁2
线程2获取锁1失败,已重试
线程1获取到了锁2
线程1获取到了2把锁
线程2获取到了锁2
线程2获取到了锁1
线程2获取到了2把锁

 6LockInterruptibly()

 相当于tryLock(long time, TimeUnit unit)把超时时间设置为无限。在等待锁的过程中,线程可以被中断

6.1代码

package cn.butool.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockInterruptiblyTest implements Runnable{
    public static void main(String[] args) {
        LockInterruptiblyTest lockInterruptiblyTest = new LockInterruptiblyTest();
        Thread thread1 = new Thread(lockInterruptiblyTest);
        Thread thread2 = new Thread(lockInterruptiblyTest);
        thread1.start();
        thread2.start();
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread1.interrupt();
    }
    private Lock lock = new ReentrantLock();
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"尝试获取锁");
        try {
            lock.lockInterruptibly();
            try {
                System.out.println(Thread.currentThread().getName()+"拿到了锁");

                Thread.sleep(5000);
            }catch (Exception e){
                System.out.println(Thread.currentThread().getName()+"睡眠期间被中断了");
            }
            finally {
                lock.unlock();
                System.out.println(Thread.currentThread().getName()+"释放了锁");
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName()+"等锁期间被中断了");

        }
    }
}

 6.2打印

第一种情况Thread-1拿到了锁:
Thread-0尝试获取锁
Thread-1尝试获取锁
Thread-1拿到了锁
Thread-0等锁期间被中断了
Thread-1释放了锁

第二种情况Thread-0拿到了锁:
Thread-0尝试获取锁
Thread-1尝试获取锁
Thread-0拿到了锁
Thread-0睡眠期间被中断了
Thread-0释放了锁
Thread-1拿到了锁
Thread-1释放了锁

7unLock()解锁

最应该被写到finally里面,并且是第一时间写到finally里面,否则有可能会漏掉,如果漏掉有可能会使程序陷入死锁。

finally {
    lock.unlock();
    System.out.println(Thread.currentThread().getName()+"释放了锁");
}

8可见性保证

在进入synchronized锁时,会去主存中读取此时的最新数据,退出锁时将当前更新刷新到主存中

lack的加解锁和synchronized有同样的内存语义,也就是说下一个线程加锁后可以看到所有前一个线程解锁前发生的所有操作

 

Lock锁的方法使用 文章目录1 Lock1.1 lock() 方法1.2 tryLock()方法与 tryLock(long time, TimeUnit unit)方法1.3 lockInterruptibly() 方法2 ReentrantLock2.1 lock() 的 正确使用方法2.2 tryLock()的使用方法2.3 lockInterruptibly() 响应中断的使用方法3 ReadWriteLock4 ReentrantReadWriteLock 1 Lock 通过查看 Lock 的源码可知 阅读详情

相关推荐

android+音乐节拍检测,科学网—音乐节拍跟踪或音乐节拍检测软件,LilyBeats alpha - 石自强的博文...

我们设计并实现了一种用于实时跟踪音乐节拍的软件。该软件可以用于智能灯方案提供商,为其提供灯光随音乐变化的核心解决方案。首先给出软件的下载链接:或者音乐节拍是乐曲中表示固定单位时值和强弱规律的组织形式,亦称拍子。它有两个特性:周期性和连续性。节拍周期性表现为节拍结构,是乐曲中周期性出现的节奏序列。节拍连续性表现为音乐的平均速度,其单位为bpm(beat per minute每分钟音乐节拍的个数)。音...

weixin_39571403的博客 1400

Java中的Lock详解

简介 java.util.concurrent.locks.Lock 是一个类似于synchronized 块的线程同步机制。但是 Lock比 synchronized 块更加灵活。Lock是个接口,有个实现类是ReentrantLock。 Lock和syncronized的区别

向上的"狼"的博客 2万+

AI Agent Harness Engineering 监控与日志系统搭建

在生成式AI(Generative AI)与大语言模型(LLM)普及的今天,AI Agent(自主智能代理)已经成为了继「LLM API调用」「单轮/多轮对话」之后的第三代AI应用范式——Agent能够自主感知环境、制定多步决策、调用外部工具(Web搜索、数据库、RAG检索、企业系统API等)、执行复杂任务并优化自身策略。然而,随着Agent应用从Demo原型快速落地到企业生产环境,一系列与工程化落地强绑定的可观测性(Observability)问题正在成为Agent项目成功上线、稳定运行的最大瓶颈。

AI开发架构师 183

Java中Lock锁详解

在Java中,Lock是一个接口,它提供了比关键字更高级的线程同步机制。使用Lock接口可以创建更复杂和灵活的同步结构。Lock接口的常用实现类有ReentrantLock和ReentrantReadWriteLock,它们提供了可重入的互斥锁和读写锁。使用Lock锁的一般步骤如下:1. 创建一个`Lock`对象实例。2. 在需要进行同步的代码块中,通过调用`lock()`方法来获取锁。3. 在同步的代码块执行完之后,通过调用`unlock()`方法释放锁。

mercedes_benz 8292

机器视觉最全面试题总结

空洞卷积(Atrous Convolution)也叫做膨胀卷积、扩张卷积,最初的提出是为了解决图像分割在用下采样(池化、卷积)增加感受野时带来的特征图缩小,后再上采样回去时造成的精度上的损失。空洞卷积通过引入了一个扩张率的超参数,该参数定义了卷积核处理数据时各值的间距。可以在增加感受野的同时保持特征图的尺寸不变,从而代替下采样和上采样a. 是普通的卷积过程(dilation rate = 1),卷积后的感受野为3b. 是dilation rate = 2的空洞卷积,卷积后的感受野为5。

@bangbang的博客 9204

【Unity动画系统】详解Root Motion动画在Unity中的应用(一)

什么时候勾选Bake into pose,当不希望动画带动游戏对象旋转时。在旋转的动画中一般是不用勾选的,因为就需要用它来带动我们的角色对象旋转。但在比如前进、后退、待机等动画来说,我们就可以勾选这里,以避免因动画文件本身的瑕疵而给我们带来的旋转。loop match:代表了这个动画在角度上的吻合度。如果这个动画在播放中转角过大,那么就会显示红色,告诉我们如果勾选bake into pose,则会带来不好的效果。

weixin_60154963的博客 6802

java中的Lock锁

本文介绍了Java中的Lock接口及其实现类ReentrantLock和ReadWriteLock。与synchronized关键字相比,Lock提供了更灵活的锁机制,包括可中断锁、公平锁、读写锁等功能。Lock接口包含lock()、tryLock()、lockInterruptibly()等方法,需要手动释放锁。Condition接口配合Lock可实现选择性通知机制。ReadWriteLock通过分离读锁(共享)和写锁(排他)提高并发性能:多个读操作可同时进行,但写操作互斥且优先于读操作。文中通过代码示例

纯洁的小魔鬼 1万+

STM32CubeIDE之SHT3X温湿度传感器移植HAL库

有了前面的OLED的学习,这个学习起来也很快。 分以下几步走 1.你要有个温度传感器,SHT3X这个型号的,因为我要讲这个 2.你要有个STM32开发板(我用的是STM32L431RCT) 3.顺便找台电脑下载一个STM32CubeIDE 4.简单的找一个SHT3X的驱动,我是去某宝嫖的,一般卖这个的都有,这个驱动分两个文件,是.c和.h的,我直接把这两个放在下边 读了我上一篇的人,看这个应该很熟悉吧,一样的套路,学习方法是一样的,你就照搬就行 下面是sht3x.c的原文档,里面有个CRC..

qq_47736089的博客 2313

Java lock锁的一些细节

前言 lock是Java接口,采用乐观锁的设计思想,采用CAS操作来实现的一个锁,这几点跟synchronized不同,synchronized原始采用的是CPU悲观锁机制, 参考博客 深入Lock锁底层原理实现,手写一个可重入锁 ...

笔记小屋 1468

17 指挥AI写Mamba相关模型代码,快速适配大模型场景

本文为《30天掌控AI编程:从指令到落地,手把手教你指挥AI写代码》系列第十七篇,属于第三阶段多场景实战核心内容。本篇聚焦当下大模型领域热门的**Mamba架构**,针对零基础大模型开发、无深度学习基础的使用者,拆解指挥AI生成Mamba基础模型、微调适配、推理部署代码的核心方法,覆盖Mamba基础模块搭建、简易序列建模、小样本微调、本地推理等高频场景,提供可直接复用的高质量指令模板、完整可运行代码、环境配置与避坑指南,无需精通Transformer、状态空间模型等底层原理,轻松上手Mamba大模型开发。

coreopt的博客 61

机器人全局路线规划导读

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对全局路线规划导读做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容。

qq_35635374的博客 1504

java lock锁的是什么意思_浅析JAVA Lock锁原理

同样是锁,先说说synchronized和lock的区别:synchronized是java关键字,是用c++实现的;而lock是用java类,用java可以实现synchronized可以锁住代码块,对象和类,但是线程从开始获取锁之后开发者不能进行控制和了解;lock则用起来非常灵活,提供了许多api可以让开发者去控制加锁和释放锁等等。写个Demostatic Lock lock = new R...

weixin_39944542的博客 322

ABAP 平台下配置 OAuth 2.0 Authorization Code 授权类型的完整指引

本文是面向ABAP管理员和SAP开发者的OAuth 2.0授权码配置实战指南。文章详细介绍了在ABAP平台启用Authorization Code的完整流程,包括前置条件检查(如TLS配置和系统用户准备)、SOAUTH2事务码中各字段配置要点(授权类型启用、Redirect URI设置、授权码有效期等)、Scope分配规则以及验证方法。通过一个销售订单OData接口的实际案例,说明了如何将抽象规范转化为具体配置。最后提供了多种验证方式(事务码测试、端点测试和Postman测试)以及关键配置参数(如授权码有效

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 296

Java 中Lock接口锁的使用

在Java中, 接口是 包中的一部分,它提供了比 更丰富的锁操作。 接口的实现类包括 (可重入锁)、(读写锁) 等。 是 Java 中 包下的一个可重入锁实现。可重入锁意味着一个线程可以多次获得同一把锁,而不会产生死锁。

精神小牛马 3199

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

java中Lock锁实现原理

java中Lock锁实现原理

SO_zxn的博客 1273

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

java Lock常用锁

java Lock常用锁及示例

1167

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java中的Lock锁

Lock锁介绍:在java中可以使用 synchronized 来实现多线程下对象的同步访问,为了获得更加灵活使用场景、高效的性能,java还提供了Lock接口及其实现类ReentrantLock和读写锁 ReentrantReadWriteLock。 相比synchronized来实现同步,使用Lock实现同步主要有以下差异性: 1、使用synchronized关键字时,锁的控制和释放是在syn

Forever-守望 904

Java 初识Lock锁和Synchronized

我们模拟一个卖票系统,演示并发 1.三个线程同时卖票,我们可以看到控制台圈红的输出信息,剩余的票是杂乱无序的 2.以前我们解决这个问题只需要加一个关键字 synchronized即可 初识Lock锁,我们同样用代码演示,主要看圈红的步骤 Lock锁和Synchronized区别 1.Synchronized 是我们java中的关键字,Lock 是一个java类 2.Synchronized 无法获取锁的状态,Lock 可以判断是否获取到锁 3.Synchronized 可以自动释放锁,Lock 需

weixin_45452416的博客 2029

java中lock方法,java中lock获取锁的四种方法

在java接口中会存放着许多方法,方便线程使用时的直接调用。对于lock接口大家都不陌生,我们已经初步对概念进行了理解。那么在获取锁的方法上想必还不是很清楚。下面我们就lock获取锁的四种方法分别进行概念的介绍,然后就其中的tryLock()方法带来实例代码的展示。1.获取方法lock()、tryLock()、tryLock(long time, TimeUnit unit) 和 lockInte...

weixin_42651887的博客 2829

Java—Lock锁

https://blog.youkuaiyun.com/weixin_43214609/article/details/101627433 参照上面的博客,得知Synchronized锁是一个重量级的锁,效率很低,而且隐式加解锁,非常不方便。 那么Java中也有一个自己实现的锁机制——Lock锁。 Lock锁是纯用Java实现的,可以看到底层源代码的那种。 1.Lock 在Java中是一个接口,是J...

致宁的大博客! 297

java 锁 Lock接口详解

1、可重入锁如果锁具备可重入性,则称作为 可重入锁。像 synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了 锁的分配机制:基于线程的分配,而不是基于方法调用的分配。举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。method2();

Not_Look_Back的博客 919

java中Lock锁的应用简介

说到java,就不能不提多线程和锁,这篇文章简单介绍一下java中Lock的几种常用的应用方式。先简单介绍一下锁。锁,顾名思义,就是可以把东西锁住,在java里,可以理解为把一段代码锁住,只能让一个线程访问并执行,其他线程想再执行这段代码,就要等前面的线程结束才可以。

nhx900317的博客 1925

java:lock锁

synchronized锁效率比较低,不方便扩展,不能自定义。于是从jdk1.5之后,就引入了lock锁。 lock可以手动上锁,手动释放锁,灵活性很高。 Lock lock = new ReentrantLock(); lock.lock(); try{ // 可能会出现线程安全的操作 }finally{ // 一定要在finally中释放锁 ...

m0_37564426的博客 266

java Lock锁详解

1.公平锁:就是很公平,在并发环境中,每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规则从队列中取到自己。await(long time, TimeUnit unit):使当前线程等待一段时间,在指定的时间内没有被其他线程调用signal()或signalAll()方法唤醒,将自动唤醒。await():使当前线程等待,直到被其他线程调用signal()或signalAll()方法唤醒。

qq_42077317的博客 2644

Java并发之 Lock 锁

锁是一种工具,用于控制对共享资源的访问Lock和synchronized是最常见的两个锁,他们都能够达到线程安全的目录,但是使用和功能上又有较大的不同Lock接口最常见的实现类就是通常情况下Lock只允许一个线程访问共享资源,特殊情况也允许多个线程并发访问,如ReadWriteLock的ReadLock悲观锁认为:如果我不锁住这个资源,别人就会来争抢,就会造成数据结果错误,所以为了结果的正确性,悲观锁会在每次获取并修改结果时把数据锁住,让别人无法访问。

Qynwang的博客 2743

java lock锁的是什么意思_Java中lock锁的问题

Lock锁分为以下几种,可重入锁,非可重入锁,公平锁,非公平锁,读写锁。可重入锁:synchronized和ReentrantLock锁均为可重入锁。当在一个获得了锁的方法中,调用另外一个需要获得锁的方法时,如果此时为可重入锁,则正常运行。如果为非可重入锁,则系统报错。公平锁:一个线程在等待着另外线程释放资源时,当新加入另一个线程时,如果采取的是公平锁,则按照等待时间的先后顺序依次获得资源。假如采...

weixin_31364787的博客 1118
上一篇: java--ThreadLocal详解
下一篇: centos7 配置密钥登录
别浪呀
博客等级 码龄8年 1万+粉丝 260原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值