并发编程之没有条件创造条件Condition

简介: 多线程编程必会内容, 锁条件Lock.Condition

作者: 西魏陶渊明
博客: https://blog.springlearn.cn/

Condition 是为了调换 Object 中的 wait()
和notify().

API Object Condition
等待 wait() wait()
通知 notify() signal()
通知所有 notifyAll() signalAll()

wait是会释放锁

相同点

  • 都必须被包裹在同步代码块中,即加锁
  • 当调用wait都会释放锁

不同点

  • Object 依赖 synchronized 锁
  • Condition 依赖 Lock 锁

ObjectWait

::: tip 运行结果

  • 当前线程进入线程一
  • 当前线程进入线程二
  • 当前线程释放main
  • 当前线程释放main
  • 当前线程退出线程一
  • 当前线程退出线程二

:::

/**
 * @author liuxin
 * 2022/1/5 12:24 上午
 */
public class ObjectWait {

    public synchronized void objWait() throws Exception {
        System.out.println("当前线程进入" + Thread.currentThread().getName());
        wait();
        System.out.println("当前线程退出" + Thread.currentThread().getName());
    }

    public synchronized void objNotify() throws Exception {
        System.out.println("当前线程释放" + Thread.currentThread().getName());
        notify();
    }

    public static void main(String[] args) throws Exception {
        ObjectWait objectWait = new ObjectWait();
        // 使用synchronized修饰方法,就是锁的是当前这个示例synchronized(this)
        new Thread(() -> {
            try {
                // 当前进入等待,然后释放锁。wait会释放锁
                objectWait.objWait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"线程一").start();

        // 使用synchronized修饰方法,就是锁的是当前这个示例synchronized(this)
        new Thread(() -> {
            try {
                // 当前进入等待,然后释放锁。wait会释放锁
                objectWait.objWait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"线程二").start();
        Thread.sleep(1000L);
        // 释放锁后才会放行
        objectWait.objNotify();
        // 释放锁后才会放行
        objectWait.objNotify();
    }
}

LockWait

::: tip 运行结果

  • 当前线程进入线程一
  • 当前线程进入线程二
  • 当前线程释放main
  • 当前线程释放main
  • 当前线程退出线程一
  • 当前线程退出线程二

:::

/**
 * @author liuxin
 * 2022/1/5 24:24 上午
 */
public class LockWait {

    private ReentrantLock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();

    public void lockWait() throws Exception {
        lock.lock();
        System.out.println("当前线程进入" + Thread.currentThread().getName());
        condition.await();
        System.out.println("当前线程退出" + Thread.currentThread().getName());
        lock.unlock();
    }

    public void lockNotify() {
        lock.lock();
        System.out.println("当前线程释放" + Thread.currentThread().getName());
        condition.signal();
        lock.unlock();
    }

    public static void main(String[] args) throws Exception {
        LockWait lockWait = new LockWait();
        // lock.lock()  线程一: 获取锁,然后wait之后,进入释放锁,然后进入到等待队列
        new Thread(() -> {
            try {
                // 当前进入等待,然后释放锁。
                lockWait.lockWait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "线程一").start();
        // lock.lock()  当前线程二获取锁,然后wait之后,进入释放锁,然后进入到等待队列
        new Thread(() -> {
            try {
                // 当前进入等待,然后释放锁。
                lockWait.lockWait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"线程二").start();

        Thread.sleep(1000L);
        // 调用第一次,会唤醒线程一,继续向下执行
        lockWait.lockNotify();
        // 调用第二次,会唤醒线程二,继续向下执行
        lockWait.lockNotify();
    }
}
相关文章
|
安全 算法 Linux
CentOS7 系统安全及应用
CentOS7 系统安全及应用
630 0
CentOS7 系统安全及应用
|
15天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
在AI技术快速落地办公场景的当下,市面上绝大多数智能工具依旧停留在问答对话、文本摘要、简单文案改写层面,只能完成碎片化单点任务。企业员工处理一份完整业务工作时,往往需要同时开启多款工具,文档处理、数据分析、素材创作、网页制作分属不同软件,中间内容需要反复复制粘贴,即便借助通用大模型生成内容,输出成果还需要大量二次格式调整,才能达到交付标准。同时企业内部的数据分散在聊天记录、审批单据、本地文档、业务平台,普通AI工具无法直接读取内部业务信息,每一次任务都要人工复述背景条件,法务、财务、研发这类垂直岗位,还需要编写冗长提示词才能拿到相对可用结果,AI办公落地的实际门槛长期居高不下。千问办公Qwen
385 5
|
1月前
|
SQL 人工智能 运维
3个月AI Agent运维实测:慢SQL它管,根因还得我上
以三个月实测的视角,划清AI Agent自治运维的真实能力边界:巡检、慢SQL发现等重复活已可替代,复杂根因、变更审批、数据兜底仍需人把关,探讨DBA角色从救火队员向定规则、把关人的转型。
|
2月前
|
弹性计算 缓存 运维
阿里云服务器贵不贵?一文看懂阿里云服务器多少钱:配置价格表、优惠福利、计费选型避坑指南
很多个人开发者、学生、中小企业在上云初期,都会关心云服务器的实际采购成本。阿里云服务器主要分为轻量应用服务器与云服务器ECS两大产品线,覆盖个人入门学习、开发者测试、中小型企业生产、高性能计算等不同层级业务场景。整体价格跨度很大,入门档位低价即可入手,高性能实例则可达数万元每年,整体呈现“入门普惠、中阶稳定、高阶弹性”的特征。新用户拥有力度可观的折扣,部分实例支持老用户续费同价,长期使用成本可控。本文将从产品定位、配置价格明细、性价比分析、各类人群优惠政策、三种计费模式、命令行实操、省钱技巧、常见避坑点多维度完整讲解,附带可直接复制的CLI命令,帮助使用者合理选型,规避多花冤枉钱的问题。
271 0
|
9月前
|
存储 缓存 编解码
阿里云高配置云服务器解析:4 核 16G、8 核 16G、8 核 32G 实例特性与价格说明
阿里云高配置云服务器以 4 核 16G、8 核 16G、8 核 32G 为核心规格,覆盖通用型、计算型、通用平衡增强型等多类实例,适配企业高并发服务、大数据处理、复杂应用部署等核心场景。不同实例通过差异化硬件架构与性能优化,满足从个人开发者到大型企业的多元需求,同时依托优惠政策降低高性能算力的获取成本。本文结合实例特性、价格体系及适用场景,为用户提供客观选型参考。
|
11月前
|
JavaScript 前端开发 Java
【JAVA全栈项目】弧图图-智能图床 SpringBoot+Vue3 :[框架开荒:一文全步骤打通前后端项目全流程]
该文档详细介绍弧图图智能图床平台的前后端框架搭建步骤。后端基于 SpringBoot,整合 MybatisPlus、knife4j 等依赖,配置了异常处理、统一响应体等;前端用 Vue3+TypeScript,引入 Ant Design Vue,实现布局、路由、Axios 请求等功能,完成基础框架搭建。
848 0
【JAVA全栈项目】弧图图-智能图床 SpringBoot+Vue3 :[框架开荒:一文全步骤打通前后端项目全流程]
|
图形学 开发者
【Unity3D实例-功能-镜头】第三人称视觉-镜头优化
本文介绍了如何在Unity中使用Cinemachine调整第三人称视角镜头,适用于ARPG游戏开发。内容包括调整摄像机Y轴方向与速度、设置转向灵敏度以及实现摄像机跟随角色平移,帮助开发者快速掌握镜头控制技巧。
593 0
|
安全 Shell 定位技术
抖音修改位置信息怎么改?
抖音虚拟定位技术实现原理与代码实战 一、技术背景与原理分析
|
存储 缓存 前端开发
《从网页到桌面:PWA如何借两大核心实现离线启动》
本文围绕PWA应用的离线安装与启动展开,深入解析Web App Manifest与Service Workers的协同作用。Manifest为PWA赋予设备端“身份标识”,通过定义应用名称、图标、显示模式等,使其脱离浏览器束缚,以类原生形态被用户安装调用,强化品牌认知与使用便捷性。Service Workers作为后台引擎,通过智能缓存关键资源实现快速启动,并在离线时拦截请求、切换缓存模式,保障核心功能可用。二者协同打破网页对网络的强依赖,让PWA兼具网页的分发灵活性与原生应用的驻留可靠性,为用户提供全场景稳定体验,也为开发者简化跨平台适配,重塑前端应用的分发与使用模式。
441 0
|
人工智能 JavaScript 程序员
Fitten Code:在VSCode插件市场备受欢迎的原因是什么?
随着AI技术的不断发展,AI在编写代码方面的能力也日益强大。充分利用AI的能力能够显著提高代码编写的效率和质量。今天我将向大家介绍一款备受瞩目的AI代码神器——Fitten Code,让我们一同揭开它神秘的面纱!
1494 3