当前位置: 首页 > news >正文

Java 多线程编程核心要点全解析:深度探秘关键方法与同步机制

1.Thread 类中的start() 和 run() 方法有什么区别?

在Java编程语言中,Thread 类的 start() 和 run() 方法有重要的区别:

start() 方法:

  • 当你调用 start() 方法时,它会启动一个新的线程,并且这个新线程会执行 run() 方法中的代码。
  • start() 方法的调用会导致 JVM 创建一个系统级别的线程,这将使程序真正地并发执行。
  • 一旦 start() 方法被执行,它就会立即返回给调用它的线程(即原来的线程),而新的线程则开始运行。
  • 每个线程只能调用一次 start() 方法。多次调用会导致 IllegalThreadStateException。

run() 方法:

  • run() 方法包含了线程需要执行的代码。它是线程的入口点,类似于主函数是程序的入口点。
  • 如果你直接调用 run() 方法,它会在当前线程中像普通的方法调用一样执行,不会开启新的线程,因此也不会实现并发。
  • 直接调用 run() 不会利用到多线程的优势,因为实际上没有创建新的线程来并行处理任务。

总结来说,要让线程并发运行,你应该使用 start() 方法,而不是直接调用 run() 方法。如果你只是想执行 run() 方法中的代码而不关心是否是在线程上下文中执行,那么你可以直接调用 run() 方法,但这通常不是我们使用线程的目的。

2.为什么wait, notify 和 notifyAll这些方法不在thread类里面?

wait(), notify(), 和 notifyAll() 方法并不在 Thread 类中,而是在 Object 类中定义的。这是因为这些方法与对象的内部状态监控有关,而不是直接与线程的生命周期管理相关。以下是几个原因解释为什么这些方法被设计为 Object 类的一部分:

对象锁(Monitor):

  • 每个Java对象都有一个关联的锁(也称为监视器)。当线程需要对某个对象进行同步操作时,它必须首先获取该对象的锁。
  • wait(), notify(), 和 notifyAll() 方法是用于协调线程间基于对象锁的通信。

条件等待:

  • 这些方法允许线程在满足特定条件之前暂停执行,并释放对象锁。当条件发生变化时,可以通过 notify() 或 notifyAll() 唤醒等待中的线程。
  • 因为条件通常是与对象的状态相关的,所以将这些方法放在 Object 类中可以确保它们作用于正确的对象实例上。

避免竞争条件:

  • 通过让这些方法成为 Object 的一部分,可以保证任何对这些方法的调用都必须在一个已经获得相应对象锁的同步代码块或方法内进行。这有助于防止竞争条件和其他并发问题。

灵活性和复用性:

  • 将这些方法放在 Object 类中意味着所有Java类都可以使用它们,无需额外实现。这样可以在任意对象上创建生产者-消费者模式或其他线程协作模式,增加了代码的灵活性和可复用性。

语义清晰:

  • 把这些方法放在 Object 类里,能够更明确地表达出它们的作用范围是针对具体对象的,而不是整个线程的行为。因此,程序员可以更容易理解哪些线程在等待哪个对象的条件变化。

总之,wait(), notify(), 和 notifyAll() 方法的设计决策反映了Java对于对象级别的并发控制的关注,以及如何有效地管理和协调多个线程之间的交互。

3.为什么wait和notify方法要在同步块中调用?

wait() 和 notify() 方法必须在同步块(synchronized block)或同步方法(synchronized method)中调用,原因如下:

确保线程安全:

  • 当一个线程调用对象的 wait() 方法时,它会释放该对象的锁,并进入等待状态。为了确保在线程释放锁之前对共享数据的操作已经完成并且是可见的给其他线程,必须在持有对象锁的情况下调用 wait()。
  • 类似地,当一个线程调用 notify() 或 notifyAll() 时,它应该保证当前线程已经更新了所有需要改变的状态信息,并且这些更改对于其他等待中的线程是可见的。

避免非法监控器状态异常 (IllegalMonitorStateException):

  • 如果一个线程试图在没有持有适当锁的情况下调用 wait(), notify(), 或 notifyAll(),将会抛出 IllegalMonitorStateException。这是因为这些方法设计为只能由拥有对象监视器(即对象锁)的线程来调用。

维护条件变量的一致性:

  • wait() 和 notify() 是用来协调线程间基于特定条件的变化。例如,在生产者-消费者问题中,当缓冲区满时,生产者应该等待;当缓冲区空时,消费者应该等待。这种情况下,只有当线程持有相关对象的锁时,才能正确检查和修改条件变量,从而确保条件的一致性和正确性。

防止忙等待 (Busy Waiting):

  • 在没有同步机制的情况下,线程可能会持续不断地检查某个条件是否满足,这会导致不必要的CPU资源浪费。通过使用 wait() 和 notify() 并结合同步块,可以有效地让线程在条件不满足时休眠,并在条件发生变化时被唤醒,从而提高效率。

实现正确的线程通信:

  • 同步块确保了线程之间的有序通信。当一个线程调用了 wait(),它会被挂起直到另一个线程调用了 notify() 或 notifyAll()。这种方式保证了线程间的通信是按照预期进行的,而不会出现混乱或无序的情况。

综上所述,将 wait() 和 notify() 放在同步上下文中调用是为了确保操作的安全性、正确性以及高效的线程间协作。这是Java并发编程模型的一部分,旨在帮助开发者编写稳定可靠的多线程程序。

4.Java中interrupted 和 isInterruptedd方法的区别?

在Java中,interrupted() 和 isInterrupted() 方法都是用来检查线程是否被中断的,但它们之间有一些关键的区别:

Thread.interrupted():

  • 这是一个静态方法。
  • 它会清除当前线程的中断状态。也就是说,如果线程已经被中断了,调用此方法后,该线程的中断标志将被设置为false。
  • 它只对当前线程有效,即它总是检查并可能清除调用它的那个线程的中断状态。
  • 如果线程未被中断,则返回false;如果线程已被中断,则返回true,并且同时将线程的中断状态重置为未中断。

Thread.isInterrupted():

  • 这是一个实例方法。
  • 它不会改变线程的中断状态,只会查询线程的中断状态。因此,它可以多次调用而不会影响中断标志。
  • 它可以用于任何线程实例,不仅仅是当前线程。你可以通过传递一个线程对象来检查该线程是否被中断。
  • 如果线程被中断,则返回true;否则返回false,且不会修改中断状态。

示例代码

Thread thread = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {// 执行任务...}
});thread.start();
// 一些时间后...
thread.interrupt();// 检查并清除中断状态(仅适用于当前线程)
boolean wasInterrupted = Thread.interrupted(); // 返回 truefalse 并清除中断状态// 检查其他线程的中断状态而不清除它
boolean isThreadInterrupted = thread.isInterrupted(); // 只返回 true 或 false,不改变状态

总结

  • 使用 Thread.interrupted() 来检测和清除当前线程的中断状态。
  • 使用 Thread.isInterrupted() 来单纯地检测某个特定线程的中断状态,而不会对其做任何改变。

理解这两个方法之间的区别对于正确处理线程中断非常重要,尤其是在编写多线程应用时。

5.Java中synchronized 和 ReentrantLock 有什么不同?

在Java中,synchronized 关键字和 ReentrantLock 类都提供了同步机制,用于控制多个线程对共享资源的访问。然而,它们之间有一些关键的不同点:

1. 使用方式

synchronized:

  • 是一种内置的语言特性,使用起来非常简单。可以通过声明同步方法或同步代码块来使用。
  • 同步方法是通过在方法定义前加上 synchronized 关键字来实现的;同步代码块则是通过 synchronized(object) { … } 的形式,其中 - object 是你想要同步的对象。

ReentrantLock:

  • 是一个显式的锁对象,需要从 java.util.concurrent.locks 包中导入。
  • 使用时需要手动获取锁(lock() 方法)和释放锁(unlock() 方法)。通常会结合 try-finally 或者 Java 7 引入的 try-with-resources 来确保锁最终会被释放。

2. 功能特性

synchronized:

  • 自动管理锁的获取与释放:当线程进入同步代码块或方法时自动获得锁,退出时自动释放锁。
  • 支持可重入锁:如果同一个线程再次请求已经持有的锁,不会导致死锁。
  • 没有提供尝试锁定、定时锁定等高级功能。

ReentrantLock:

  • 提供了更多的灵活性和更强大的功能,比如:
  • 尝试锁定(tryLock()),允许线程尝试获取锁而不被阻塞。
  • 定时锁定(tryLock(long time, TimeUnit unit)),可以在指定时间内等待锁。
  • 可中断的锁定(lockInterruptibly()),使等待中的线程可以响应中断。
  • 支持公平锁策略,即可以选择按照请求顺序分配锁。
  • 允许绑定多个条件(Condition 对象),这比 synchronized 块中的单一等待集更加灵活。

3. 性能差异

  • 在早期版本的Java中,synchronized 的性能往往不如 ReentrantLock,因为 synchronized 需要依赖于JVM级别的锁膨胀机制。不过,在Java 6及之后的版本中,synchronized 的性能得到了极大的优化,很多情况下它的性能与 ReentrantLock 相当,甚至更好。

4. 锁的粒度

  • synchronized 的粒度通常是整个方法或代码块,而 ReentrantLock 可以提供更细粒度的控制,因为它允许程序员精确地决定在哪里获取和释放锁。

结论

选择 synchronized 还是 ReentrantLock 取决于具体的需求。如果你只需要简单的同步,并且不需要上述提到的 ReentrantLock 的额外特性,那么 synchronized 是一个简洁的选择。但是,如果你需要更复杂的锁定行为或者更好的控制,那么 ReentrantLock 可能是一个更好的选择。

相关文章:

Java 多线程编程核心要点全解析:深度探秘关键方法与同步机制

1.Thread 类中的start() 和 run() 方法有什么区别? 在Java编程语言中,Thread 类的 start() 和 run() 方法有重要的区别: start() 方法: 当你调用 start() 方法时,它会启动一个新的线程,并且这个新线程会…...

个人博客接入github issue风格的评论,utteranc,gitment

在做个人博客的时候,如果你需要评论功能,但是又不想构建用户体系和评论模块,那么可以直接使用github的issue提供的接口,对应的开源项目有utteranc和gitment,尤其是前者。 它们的原理是一样的:在博客文章下…...

搞个项目之-esp32-cam ov2640模组搭建图像视频项目

开发版的介绍: 1、开发板使用的是:ESP32-CAM 2、摄像头模组:OV2640 3、烧录底座:ESP32-CAM开发板烧录座 4、mirco usb线,四线30cm 5、开发版的原理图像 项目前期的准备工作 一、安装arduino arduino官网地址地址…...

【FPGA开发】Vivado自定义封装IP核,绑定总线

支持单个文件的封装、整个工程的封装,这里用单个文件举例。 在文件工程目录下,自建一个文件夹,里面放上需要封装的verilog文件。 选择第三个,指定路径封装,找到文件所在目录 取个名,选择封装IP的路径 会…...

Leetcode51:N 皇后

题目描述: 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问…...

C#面向对象之访问限制,类基础,继承

文章目录 1 访问限制1.1 简介 2 类基础讲解2.1 类定义2.2 构造函数2.2.1 构造函数2.2.2 静态构造函数2.2.3 初始化顺序2.2.4 对象初始化器 2.3 析构函数2.4 类的静态成员2.5 匿名对象2.5.1 定义2.5.2 匿名对象的创建 3 继承3.1 基类和派生类3.2 基类初始化3.3 Partial类3.3.1 定…...

科研小白成长记41——享受大起大落

一直内心对自己的定位是喜欢安安静静生活的人,但是朋友提醒我我的生活一直都是出于各种冒险之中,从GAP申博,到GAP找工作,都不是一个乐于安于现状的人会做出来的。仔细想想不无道理,既然如此,那就如享受安静…...

正则表达式笔记

一、基本正则 常见元字符 元字符说明^以某个字符开头$以某个字符结尾.匹配任意单字符*对前一项进行0次或者多次重复匹配{m,n}将前一项字符重复m-n次,{m,},{,n},{m,n}[]对方括号内的单字符进行匹配[^]不匹配方括号内的单字符^[]匹配以某个字符开头的行(…...

解决本地运行SuperPoint_SLAM报错ERROR: flag ‘flagfile‘ was defined more than once

解决本地运行SuperPoint_SLAM报错ERROR: flag flagfile was defined more than once 起因使用LD_DEBUG排查链接过程用ldd查看各自链接的库解决办法问题解决 起因 在之前本地编译了opencv-3.4.2,当时因为contrib模块需要gflags,重新下载了一个gflags在本…...

springboot信息化在线教学平台的设计与实现(代码+数据库+LW)

摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了信息化在线教学平台的开发全过程。通过分析信息化在线教学平台管理的不足,创建了一个计算机管理信息化在线教学平台的方案。文章介绍了信息化在线教…...

maxun爬虫工具docker搭建

思路来源开源无代码网络数据提取平台Maxun 先把代码克隆到本地(只有第一次需要) git clone https://github.com/getmaxun/maxun.git 转到maxun目录 cd maxun 启动容器 docker-compose --env-file .env up -d 成功启动六个容器 网址 http://local…...

高效 Python Web 开发:FastAPI 入门与实践

高效 Python Web 开发:FastAPI 入门与实践 目录 ✨ 1. 安装与环境配置 📦 安装 FastAPI 和 Uvicorn🗂️ 项目目录结构和初始化🚀 创建一个简单的 FastAPI 项目 🛠️ 2. FastAPI 路由与请求处理 🛣️ 基本…...

C++中的函数重载

函数重载是指在同一个作用域(通常是一个类或者一个命名空间)内,可以有多个同名函数,但是这些同名函数的参数列表(参数的个数、类型或者顺序)不同。当调用这个函数名时,编译器会根据传入的实际参…...

达梦数据库常用指令都是工作中常用的

达梦数据库连接配置文件名称 cd /etc/dm_svc.conf查询 sql 日志记录是否开启:0 关闭,1/2/3开启); select SF_GET_PARA_VALUE(1,SVR_LOG)union ALL select SF_GET_PARA_VALUE(2,SVR_LOG);关闭 sql 日志记录功能 call SP_SET_PARA_VALUE(1,SVR_LOG,0);开…...

【2024最新】基于Springboot+Vue的就业信息管理系统Lw+PPT

作者:计算机搬砖家 开发技术:SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:Java精选实战项…...

linux一键部署apache脚本

分享一下自己制作的一键部署apache脚本: 脚本已和当前文章绑定,请移步下载(免费!免费!免费!) (单纯的分享!) 步骤: 将文件/内容上传到终端中 …...

修改MySQL数据库密码报1290

修改MySQL数据库密码报1290 错误 如下: alter user ‘root’‘localhost’ identified by ‘root’; ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement 需要刷新下配置 flush privileg…...

OpenCV4.8 开发实战系列专栏之 17 - 图像直方图

大家好,欢迎大家学习OpenCV4.8 开发实战专栏,长期更新,不断分享源码。 专栏代码全部基于C 与Python双语演示,领学习资料(Free) & 进专栏答疑群, VX: OpenCVXueTang_Asst 本文关键知识点:图…...

Linux下如何安装JDK

在Linux系统上安装JDK(Java Development Kit),通常包括下面步骤: 下载JDK安装包解压安装包配置环境变量等 在介绍安装之前,先厘清一些常用问题。 Linux 下Java 安装到哪个目录比较好? 在Linux系统下&am…...

实时数据开发|Flink如何实现不同数据源输入--DataSource模块

DataStream 编程模型 Flink定义DataStream API让用户灵活且高效的编写流式应用。主要分为3部分:DataSource模块,Transformation模块以及DataSink模块。 DataSource模块,主要定义了数据接入功能,将外部数据接入至flink&#xff0…...

使用Dify与BGE-M3搭建RAG(检索增强生成)应用-改进一,使用工作流代替Agnet

文章目录 前言Agent vs 工作流编写工作流 前言 在上一篇中,我们实现了一个基本的基于Dify的RAG的示范。 使用Dify与BGE-M3搭建RAG(检索增强生成)应用 这个效果确实很差。 我们一起来看看,该怎么改进。 今天我们就尝试一下&…...

GPT模型:改变世界的AI魔法师

目录 一、什么是GPT?它是怎么来的? 二、GPT能干啥?(它简直无所不能!) 三、想用GPT?这点开发技巧你一定要知道! 第一步:用OpenAI API搭建自己的GPT服务 第二步&#x…...

初识ProtoBuf以及环境搭建(Win和Ubuntu)

初始ProtoBuf 序列化和反序列化的概念 序列化:把对象转换为字节序列的过程 称为对象的序列化。 反序列化:把字节序列恢复为对象的过程 称为对象的反序列化。 什么情况下需要序列化和反序列化? 存储数据:当你想把的内存中的对象状…...

H3C OSPF实验

实验拓扑 实验需求 按照图示配置 IP 地址按照图示分区域配置 OSPF ,实现全网互通为了路由结构稳定,要求路由器使用环回口作为 Router-id,ABR 的环回口宣告进骨干区域 实验解法 一、配置IP地址 [R1]int l0 [R1-LoopBack0]ip add 1.1.1.1 32 […...

【Spark源码分析】基于Spark3.4.2源码分析SparkSQL执行过程

基于Spark3.4.2源码分析SparkSQL执行过程 文章目录 基于Spark3.4.2源码分析SparkSQL执行过程基本执行流程Unresolved逻辑计划树相关类RuleExector相关类 详细代码SparkSessionAbstractSqlParserDatasetQueryExecutionAnalyzerRuleExecutorCheckAnalysis 附录CTE简述SQL解析器Qu…...

centos8:Could not resolve host: mirrorlist.centos.org

【1】错误消息: [rootcentos211 redis-7.0.15]# yum update CentOS Stream 8 - AppStream …...

超详细ensp配置VRRP和MSTP协议

一、简介 1、什么是VRRP: (1)VRRP(Virtual Router Redundancy Protocol)的概念: VRRP(Virtual Router Redundancy Protocol)指的是一种实现路由器冗余备份的协议,常用于…...

聊聊Flink:这次把Flink的触发器(Trigger)、移除器(Evictor)讲透

一、触发器(Trigger) Trigger 决定了一个窗口(由 window assigner 定义)何时可以被 window function 处理。 每个 WindowAssigner 都有一个默认的 Trigger。 如果默认 trigger 无法满足你的需要,你可以在 trigger(…) 调用中指定自定义的 tr…...

为啥不推荐使用数据库外键

为啥不推荐使用数据库外键 前言 在阿里开发手册中写道:不得使用外键与级联,一切外键概念必须在应用层解决。 说明:(概念解释)学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更…...

C# 13 中的新增功能

C# 12 中的新增功能C# 11 中的新增功能C# 10 中的新增功能C# 9.0 中的新增功能C# 8.0 中的新增功能C#7.0中有哪些新特性?C#6.0中10大新特性的应用和总结C# 5.0五大新特性 将C#语言版本升级为预览版 C# 13 包括一些新增功能。 可以使用最新的 Visual Stu…...

sunshine+moonlight

参考自 b站视频 电脑端(发送端) 去 sunshine github 下载 https://github.com/LizardByte/Sunshine/releases/tag/v2024.1127.551下载后打开,创建用户名和密码修改配置选项,启用 UPnP,IP 地址族使用 IPv4IPv6 平板端…...

Python练习题合集

目录 一. 请编程输出其中 “超过平均身高” 的那些值。 二. 字典处理: 三. 求斐波那契数列的前若干项 四. 编程输出最长字符串的长度。 五. 去掉一个最高分,去掉一个最低分,其余分求平均作为最终分数。 六. 打印小九九乘法表 七.…...

frp 内网穿透

文章目录 前言使用自己的服务器搭建frp 这里服务器是linux centos 7 宝塔,client是 windows10 https://github.com/fatedier/frp/releases/tag/v0.53.2 版本下载分客户端与服务端 一、frp是什么?二、使用步骤1.部署服务器端2.客户端 前言 使用自己的服务…...

Vue3 子路由vue如何调用父路由vue中的方法?

1. router -> index.ts 文件: import { createRouter, createWebHistory } from vue-router import DefaultView from /views/default/index.vue import ParentView from /views/parent/index.vue import ChildView from /views/child/index.vueconst router …...

Docker 清理镜像策略详解

文章目录 前言一、删除 Docker 镜像1. 查看当前镜像2. 删除单个镜像3. 删除多个镜像4. 删除所有未使用的镜像5. 删除悬空的 Docker 镜像6. 根据模式删除镜像7. 删除所有镜像 二、删除 Docker 容器1. 查找容器2. 删除一个或多个特定容器3. 退出时删除容器4. 删除所有已退出的容器…...

Qt自定义 Qt Designer 插件

创建 Qt Designer 插件项目 Qt 提供两种设计插件的 API,可以用于扩展 Qt 的功能。高级 API 用于设计插件以扩展 Qt 的功能,例如定制数据库驱动、图像格式、文本编码、定制样式等。Qt Designer 里大量采用了插件,点击 Qt Creator 的“Help”-…...

【C语言】扫雷游戏(一)

我们先设计一个简单的9*9棋盘并有10个雷的扫雷游戏。 1,可以用数组存放,如果有雷就用1表示,没雷就用0表示。 2,排查(2,5)这个坐标时,我们访问周围的⼀圈8个位置黄色统计周围雷的个数是1。排查(8,6)这个坐标时&#xf…...

ESP32-S3模组上跑通ES8388(12)

接前一篇文章:ESP32-S3模组上跑通ES8388(11) 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回解析了es8388_init函数中的第5段代码,本回继续往下解析。为了便于理解和回顾,再次贴出es8388_init函数源码,在…...

数据集-目标检测系列- 海边漫步锻炼人检测数据集 person >> DataBall

数据集-目标检测系列- 海边漫步锻炼人检测数据集 person >> DataBall DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球…...

【论文笔记】A Token-level Contrastive Framework for Sign Language Translation

🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: A Token-level Contrastiv…...

多线程篇-9--锁的使用及分类(可重入锁,读写锁,锁降级,死锁,LockSupport,乐观锁,悲观锁,分段锁等)

1、锁的概述 Java 中,锁是一种用于控制多线程并发访问共享资源的机制。合理的锁机制可以确保线程安全,避免数据竞争和不一致的问题。 Java 提供了多种锁机制,包括内置锁(即 synchronized 关键字)、显式锁(…...

提升阅读体验,Balabolka让文字跃然“声”上

作为一个专业的语音合成工具,Balabolka为用户提供了全方位的文本朗读解决方案。这款软件不仅可以将各类文本实时转换为清晰的语音输出,还能将转换后的音频内容导出为多种主流格式。它强大的兼容性使其能够处理各类电子书和文档格式,让用户可以…...

【汇编语言】call 和 ret 指令(三) —— 深度解析汇编语言中的批量数据传递与寄存器冲突

文章目录 前言1. 批量数据的传递1.1 存在的问题1.2 如何解决这个问题1.3 示例演示1.3.1 问题说明1.3.2 程序实现 2. 寄存器冲突问题的引入2.1 问题引入2.2 分析与解决问题2.2.1 字符串定义方式2.2.2 分析子程序功能2.2.3 得到子程序代码 2.3 子程序的应用2.3.1 示例12.3.2 示例…...

嵌入式C编程:宏定义与typedef的深入对比与应用

目录 一、宏定义(Macro Definition) 1.1. 特点与应用 1.1.1 定义常量 1.1.2 定义函数式宏 1.1.3 条件编译 1.2. 作用范围和生命周期方面 1.3. 应用注意事项 二、typedef 2.1. 特点与应用 2.1.1 简化类型声明 2.1.2 提高代码可读性 2.1.3 实现…...

算法复杂度

目录: 算法的效率时间复杂度 1.算法的效率 1.1旋转数组习题分析 如何衡量一个算法的好坏呢? 案例:旋转数组(189. 轮转数组 - 力扣(LeetCode)) 思路:循环k次将所有元素向后移动一…...

时序约束进阶六:Set_Clock_Groups详解

目录 一、前言 二、时钟间关系 2.1 时钟关系分类 2.2 时钟关系查看 三、set_clock_groups设置 3.1 使用格式 3.2 优先级 3.3 约束设置示例 3.4 约束效果查看 四、Exclusive差异说明 4.1 Asynchronous 4.2 Logically_exclusive与Physically_exclusive 4.3 logical…...

《运放秘籍》第二部:仪表放大器专项知识点总结

一、差分放大器与仪表放大器的讨论 1.1. 仪放的前世今生——差分放大器原理? 1.2. 差分放大的原理 1.3. 差分放大器检测电流 1.4. 差分放大器端一:输入阻抗 1.5. 差分放大器端二:共模抑制比 1.6. 为什么关注输入阻抗?共模抑…...

JavaSE——异常

一、异常的概念 在Java中,将程序执行中发生的不正常行为称为"异常",开发过程中的语法错误和逻辑错误不是异常。 主要分为以下两大类: Error(错误):Java虚拟机无法解决的严重问题,是严重错误,程序…...

HormonyOS: 图形变换之Rotate

官网地址:rotate 1. 概述 rotate是鸿蒙系统为组件提供的旋转属性,通过rotate属性,可实现组件的旋转效果 2. rotate属性 2.1. 语法参数 rotate(value: RotateOptions) 参数: 参数名 类型 必填 说明 value RotateOptions…...

【Solidity】入门指南:智能合约开发基础

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 Solidity入门指南:智能合约开发基础引言1. 开发环境搭建1.1 Remix I…...