展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Java多线程中如何使用Lock?

Java多线程中如何使用Lock?

Jdk1.5以后,在java.util.concurrent.locks包下,有一组实现线程同步的接口和类,说到线程的同步,可能大家都会想到synchronized关键字,这是java内置的关键字,用来处理线程同步的,但这个关键字有很多的缺陷,使用起来也不是很方便和直观,所以就出现了Lock,下面,我们就来对比着讲解Lock。通常我们在使用synchronized关键字的时候会遇到下面这些问题:(1)不可控性,无法做到随心的加锁和释放锁。(2)效率比较低下,比如我们现在并发的读两个文件,读与读之间是互不影

本文目录

    Jdk1.5 以后,在 java.util.concurrent.locks 包下,有一组实现线程同步的接口和类,说到线程的同步,可能大家都会想到 synchronized 关键字,

    这是 java 内置的关键字,用来处理线程同步的,但这个关键字有很多的缺陷,使用起来也不是很方便和直观,所以就出现了 Lock,下面,我们

    就来对比着讲解 Lock。

    通常我们在使用 synchronized 关键字的时候会遇到下面这些问题:

    (1)不可控性,无法做到随心的加锁和释放锁。

    (2)效率比较低下,比如我们现在并发的读两个文件,读与读之间是互不影响的,但如果给这个读的对象使用 synchronized 来实现同步的话,

    那么只要有一个线程进入了,那么其他的线程都要等待。

    (3)无法知道线程是否获取到了锁。

    而上面 synchronized 的这些问题,Lock 都可以很好的解决,并且 jdk1.5 以后,还提供了各种锁,例如读写锁,但有一点需要注意,使用 synchronized

    关键时,无须手动释放锁,但使用 Lock 必须手动释放锁。下面我们就来学习一下 Lock 锁。

    Lock 是一个上层的接口,其原型如下,总共提供了 6 个方法:

    public interface Lock {
      // 用来获取锁,如果锁已经被其他线程获取,则一直等待,直到获取到锁
       void lock();
      // 该方法获取锁时,可以响应中断,比如现在有两个线程,一个已经获取到了锁,另一个线程调用这个方法正在等待锁,但是此刻又不想让这个线程一直在这死等,可以通过
        调用线程的Thread.interrupted()方法,来中断线程的等待过程
      void lockInterruptibly() throws InterruptedException;
      // tryLock方法会返回bool值,该方法会尝试着获取锁,如果获取到锁,就返回true,如果没有获取到锁,就返回false,但是该方法会立刻返回,而不会一直等待
       boolean tryLock();
      // 这个方法和上面的tryLock差不多是一样的,只是会尝试指定的时间,如果在指定的时间内拿到了锁,则会返回true,如果在指定的时间内没有拿到锁,则会返回false
       boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
      // 释放锁
       void unlock();
      // 实现线程通信,相当于wait和notify,后面会单独讲解
       Condition newCondition();
    }

    那么这几个方法该如何使用了?前面我们说到,使用 Lock 是需要手动释放锁的,但是如果程序中抛出了异常,那么就无法做到释放锁,有可能引起死锁,

    所以我们在使用 Lock 的时候,有一种固定的格式,如下:

    Lock l = ...;
          l.lock();
          try {
            // access the resource protected by this lock
          } finally {// 必须使用try,最后在finally里面释放锁
            l.unlock();
          }

    下面我们来看一个简单的例子,代码如下:

    /**
     * 描述:Lock使用
     */
    public class LockDemo {
        // new一个锁对象,注意此处必须声明成类对象,保持只有一把锁,ReentrantLock是Lock的唯一实现类
       Lock lock = new ReentrantLock();
       public void readFile(String fileMessage){
          lock.lock();// 上锁
          try{
             System.out.println(Thread.currentThread().getName()+"得到了锁,正在读取文件……");
             for(int i=0; i

    Lock与synchronized的对比

    1、作用

    lock 和 synchronized 都是 Java 中去用来解决线程安全问题的一个工具。

    2、来源

    sychronized 是 Java 中的一个关键字。

    lock 是 JUC 包里面提供的一个接口,这个接口有很多实现类,其中就包括我们最常用的 ReentrantLock(可重入锁)。

    3、锁的力度

    sychronized 可以通过两种方式去控制锁的力度:

    把 sychronized 关键字修饰在方法层面。
    修饰在代码块上。
    锁对象的不同:

    锁对象为静态对象或者是class对象,那这个锁属于全局锁。
    锁对象为普通实例对象,那这个锁的范围取决于这个实例的生命周期。
    lock锁的力度是通过 lock()与unlock()两个方法决定的。在两个方法之间的代码能保证其线程安全。lock的作用域取决于lock实例的生命周期。

    4、灵活性

    lock锁比sychronized的灵活性更高。

    lock可以自主的去决定什么时候加锁与释放锁。只需要调用lock 的lock()和unlock()这两个方法就可以。

    sychronized 由于是一个关键字,所以他无法实现非阻塞竞争锁的方法,一个线程获取锁之后,其他锁只能等待那个线程释放之后才能有获取锁的机会。

    5、公平锁与非公平锁

    公平锁:多个线程按照申请锁的顺序去获得锁,线程会直接进入队列去排队,永远都是队列的第一位才能得到锁。

    优点:所有的线程都能得到资源,不会饿死。
    缺点:吞吐量低,队列里面除了第一个线程,其他的线程都会阻塞,cpu唤醒阻塞线程的开销大。
    非公平锁:多个线程去获取锁的时候,会直接去尝试获取,获取不到,再去进入等待队列,如果能获取到,就直接获取到锁。

    优点:可以减少CPU唤醒线程的开销,整体的吞吐效率会高点,CPU也不必取唤醒所有线程,会减少唤起线程的数量。
    缺点:可能导致队列中间的线程一直获取不到锁或者长时间获取不到锁,最终饿死。
    lock提供了公平锁和非公平锁两种机制(默认非公平锁)。

    sychronized是非公平锁。

    6、异常是否释放锁

    synchronized锁的释放是被动的,当sychronized同步代码块执行结束或者出现异常的时候才会被释放。

    lock锁发生异常的时候,不会主动释放占有的锁,必须手动unlock()来释放,所以我们一般都是将同步代码块放进try-catch里面,finally中写入unlock()方法,避免死锁发生。

    7、判断是否能获取锁

    synchronized不能。

    lock提供了非阻塞竞争锁的方法trylock(),返回值是Boolean类型。它表示的是用来尝试获取锁:成功获取则返回true;获取失败则返回false,这个方法无论如何都会立即返回。

    8、调度方式

    synchronized使用的是object对象本身的wait、notify、notifyAll方法,而lock使用的是Condition进行线程之间的调度。

    9、是否能中断

    synchronized只能等待锁的释放,不能响应中断。

    lock等待锁过程中可以用interrupt()来中断。

    10、性能

    如果竞争不激烈,性能差不多;竞争激烈时,lock的性能会更好。

    lock锁还能使用readwritelock实现读写分离,提高多线程的读操作效率。

    11、sychronized锁升级

    synchronized 代码块是由一对 monitorenter/monitorexit 指令实现的。Monitor的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作。

    所以现在JVM提供了三种不同的锁:偏向锁、轻量级锁、重量级锁。

    偏向锁:
    当没有竞争出现时,默认使用偏向锁。线程会利用 CAS 操作在对象头上设置线程 ID ,以表示对象偏向当前线程。

    目的:在很多应用场景中,大部分对象生命周期最多会被一个线程锁定,使用偏向锁可以降低无竞争时的开销。

    轻量级锁:
    JVM比较当前线程的 threadID 和 Java 对象头中的threadID是否一致,如果不一致(比如线程2要竞争锁对象),那么需要查看 Java 对象头中记录的线程1是否存活(偏向锁不会主动释放因此还是存储的线程1的 threadID),如果没有存活,那么锁对象还是为偏向锁(对象头中的threadID为线程2的);如果存活,那么撤销偏向锁,升级为轻量级锁。

    当有其他线程想访问加了轻量级锁的资源时,会使用自旋锁优化,来进行资源访问。

    目的:竞争锁对象的线程不多,而且线程持有锁的时间也不长的情景。因为阻塞线程需要CPU从用户态转到内核态,开销大,如果刚刚阻塞不久这个锁就被释放了,就得不偿失了,因此这个时候就干脆不阻塞这个线程,让它自旋这等待锁释放。

    重量级锁:
    自旋失败,很大概率 再一次自选也是失败,因此直接升级成重量级锁,进行线程阻塞,减少cpu消耗。

    当锁升级为重量级锁后,未抢到锁的线程都会被阻塞,进入阻塞队列。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。