juc概述和Lock接口
目录
一、什么是JUC
1、JUC概述
2、进程与线程
3、线程的状态
4、wait/sleep 的区别
5、并发与并行
6、管程
7、用户线程和守护线程
二、Lock接口
1、Synchronized
使用synchronized实现售票案例
使用synchronized实现增减变量操作
2、什么是 Lock
买票例子使用lock实现
增减变量操作使用lock实现
3、newCondition
增减变量操作使用Condition实现
线程定制化执行
4、ReentrantLock
5、ReadWriteLock
一、什么是JUC
1、JUC概述
JUC 就是 java.util .concurrent 工具包的简称。这是一个处理线程的工具包,JDK 1.5 开始出现的。

2、进程与线程
3、线程的状态
public enum State {/*** Thread state for a thread which has not yet started.*/NEW, // 新建/*** Thread state for a runnable thread. A thread in the runnable* state is executing in the Java virtual machine but it may* be waiting for other resources from the operating system* such as processor.*/RUNNABLE, // 运行时/*** Thread state for a thread blocked waiting for a monitor lock.* A thread in the blocked state is waiting for a monitor lock* to enter a synchronized block/method or* reenter a synchronized block/method after calling* {@link Object#wait() Object.wait}.*/BLOCKED, // 阻塞/*** Thread state for a waiting thread.* A thread is in the waiting state due to calling one of the* following methods:* <ul>* <li>{@link Object#wait() Object.wait} with no timeout</li>* <li>{@link #join() Thread.join} with no timeout</li>* <li>{@link LockSupport#park() LockSupport.park}</li>* </ul>** <p>A thread in the waiting state is waiting for another thread to* perform a particular action.** For example, a thread that has called <tt>Object.wait()</tt>* on an object is waiting for another thread to call* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on* that object. A thread that has called <tt>Thread.join()</tt>* is waiting for a specified thread to terminate.*/WAITING, //等待/*** Thread state for a waiting thread with a specified waiting time.* A thread is in the timed waiting state due to calling one of* the following methods with a specified positive waiting time:* <ul>* <li>{@link #sleep Thread.sleep}</li>* <li>{@link Object#wait(long) Object.wait} with timeout</li>* <li>{@link #join(long) Thread.join} with timeout</li>* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>* </ul>*/TIMED_WAITING, // 过时不候/*** Thread state for a terminated thread.* The thread has completed execution.*/TERMINATED; //终结}
4、wait/sleep 的区别
5、并发与并行
并发:并发是指两个或多个事件在同一时间间隔发生。
- 例子:春运抢票 电商秒杀...
并行:并行是指两个或者多个事件在同一时刻发生。
- 例子:泡方便面,电水壶烧水,一边撕调料倒入桶中
6、管程
7、用户线程和守护线程
二、Lock接口
1、Synchronized
- 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
- 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
- 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
- 修改一个类,其作用的范围是 synchronized 后面括号括起来的部分,作用主的对象是这个类的所有对象
虽然可以使用 synchronized 来定义方法,但 synchronized 并不属于方法定义的一部分,因此,synchronized 关键字不能被继承。如果在父类中的某个方法使用了 synchronized 关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,而必须显式地在子类的这个方法中加上synchronized 关键字才可以。当然,还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的,但子类调用了父类的同步方法,因此,子类的方法也就相当于同步了。
使用synchronized实现售票案例
//第一步 创建资源类,定义属性和和操作方法
class Ticket {//票数private int number = 30;//操作方法:卖票public synchronized void sale() {//判断:是否有票if(number > 0) {System.out.println(Thread.currentThread().getName()+" : 卖出:"+(number--)+" 剩下:"+number);}}
}public class SaleTicket {//第二步 创建多个线程,调用资源类的操作方法public static void main(String[] args) {//创建Ticket对象Ticket ticket = new Ticket();//创建三个线程new Thread(new Runnable() {@Overridepublic void run() {//调用卖票方法for (int i = 0; i < 40; i++) {ticket.sale();}}},"AA").start();new Thread(new Runnable() {@Overridepublic void run() {for(int i = 0; i < 40; i ++) {ticket.sale();}}},"DD");new Thread(new Runnable() {@Overridepublic void run() {//调用卖票方法for (int i = 0; i < 40; i++) {ticket.sale();}}},"BB").start();new Thread(new Runnable() {@Overridepublic void run() {//调用卖票方法for (int i = 0; i < 40; i++) {ticket.sale();}}},"CC").start();}
}
使用synchronized实现增减变量操作
当变量为0是线程A、C将其+1,当变量为1时B、D线程将其-1
//第一步 创建资源类,定义属性和操作方法
class Share {//初始值private int number = 0;//+1的方法public synchronized void incr() throws InterruptedException {//第二步 判断 干活 通知while(number != 0) { //判断number值是否是0,如果不是0,等待this.wait(); //在哪里睡,就在哪里醒}//如果number值是0,就+1操作number++;System.out.println(Thread.currentThread().getName()+" :: "+number);//通知其他线程this.notifyAll();}//-1的方法public synchronized void decr() throws InterruptedException {//判断while(number != 1) {this.wait();}//干活number--;System.out.println(Thread.currentThread().getName()+" :: "+number);//通知其他线程this.notifyAll();}
}public class ThreadDemo1 {//第三步 创建多个线程,调用资源类的操作方法public static void main(String[] args) {Share share = new Share();//创建线程new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr(); //+1} catch (InterruptedException e) {e.printStackTrace();}}},"AA").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr(); //-1} catch (InterruptedException e) {e.printStackTrace();}}},"BB").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr(); //+1} catch (InterruptedException e) {e.printStackTrace();}}},"CC").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr(); //-1} catch (InterruptedException e) {e.printStackTrace();}}},"DD").start();}
}
如果一个代码块被 synchronized 修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
2、什么是 Lock
- Lock 不是 Java 语言内置的,synchronized 是 Java 语言的关键字,因此是内置特性。Lock 是一个类,通过这个类可以实现同步访问;
- Lock 和 synchronized 有一点非常大的不同,采用 synchronized 不需要用户去手动释放锁,当 synchronized 方法或者 synchronized 代码块执行完之后,系统会自动让线程释放对锁的占用;而 Lock 则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。
public interface Lock {void lock();void lockInterruptibly() throws InterruptedException;boolean tryLock();boolean tryLock(long time, TimeUnit unit) throws InterruptedException;void unlock();Condition newCondition();
}
lock.lock();try{//处理任务}catch(Exception ex){}finally{lock.unlock(); //释放锁}
买票例子使用lock实现
//第一步 创建资源类,定义属性和和操作方法
class LTicket {//票数量private int number = 30;//创建可重入锁private final ReentrantLock lock = new ReentrantLock(true);//卖票方法public void sale() {//上锁lock.lock();try {//判断是否有票if(number > 0) {System.out.println(Thread.currentThread().getName()+" :卖出"+(number--)+" 剩余:"+number);}} finally {//解锁lock.unlock();}}
}public class LSaleTicket {//第二步 创建多个线程,调用资源类的操作方法//创建三个线程public static void main(String[] args) {LTicket ticket = new LTicket();new Thread(()-> {for (int i = 0; i < 40; i++) {ticket.sale();}},"AA").start();new Thread(() -> {for(int i = 0; i < 40; i ++) {ticket.sale();}}, "DD");new Thread(()-> {for (int i = 0; i < 40; i++) {ticket.sale();}},"BB").start();new Thread(()-> {for (int i = 0; i < 40; i++) {ticket.sale();}},"CC").start();}
}
增减变量操作使用lock实现
//第一步 创建资源类,定义属性和操作方法
class Share {private int number = 0;//创建Lockprivate Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();//+1public void incr() throws InterruptedException {//上锁lock.lock();try {//判断while (number != 0) {condition.await();}//干活number++;System.out.println(Thread.currentThread().getName()+" :: "+number);//通知condition.signalAll();}finally {//解锁lock.unlock();}}//-1public void decr() throws InterruptedException {lock.lock();try {while(number != 1) {condition.await();}number--;System.out.println(Thread.currentThread().getName()+" :: "+number);condition.signalAll();}finally {lock.unlock();}}
}public class ThreadDemo2 {public static void main(String[] args) {Share share = new Share();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}},"AA").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}},"BB").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}},"CC").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}},"DD").start();}}
3、newCondition
注意:在调用 Condition 的 await()/signal()方法前,也需要线程持有相关的 Lock 锁,调用 await()后线程会释放这个锁,在 singal()调用后会从当前 Condition 对象的等待队列中,唤醒 一个线程,唤醒的线程尝试获得锁, 一旦获得锁成功就继续执行。
增减变量操作使用Condition实现
//第一步 创建资源类,定义属性和操作方法
class Share {private int number = 0;//创建Lockprivate Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();//+1public void incr() throws InterruptedException {//上锁lock.lock();try {//判断while (number != 0) {condition.await();}//干活number++;System.out.println(Thread.currentThread().getName()+" :: "+number);//通知condition.signalAll();}finally {//解锁lock.unlock();}}//-1public void decr() throws InterruptedException {lock.lock();try {while(number != 1) {condition.await();}number--;System.out.println(Thread.currentThread().getName()+" :: "+number);condition.signalAll();}finally {lock.unlock();}}
}public class ThreadDemo2 {public static void main(String[] args) {Share share = new Share();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}},"AA").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}},"BB").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}},"CC").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}},"DD").start();}}
线程定制化执行
让线程按顺序执行,例子:
当flag为1时,A线程打印五次;
当flag为2时,B线程打印十次;
当flag为3时,C线程打印十五次;
按顺序打印。
//第一步 创建资源类
class ShareResource {//定义标志位private int flag = 1; // 1 AA 2 BB 3 CC//创建Lock锁private Lock lock = new ReentrantLock();//创建三个conditionprivate Condition c1 = lock.newCondition();private Condition c2 = lock.newCondition();private Condition c3 = lock.newCondition();//打印5次,参数第几轮public void print5(int loop) throws InterruptedException {//上锁lock.lock();try {//判断while(flag != 1) {//等待c1.await();}//干活for (int i = 1; i <=5; i++) {System.out.println(Thread.currentThread().getName()+" :: "+i+" :轮数:"+loop);}//通知flag = 2; //修改标志位 2c2.signal(); //通知BB线程}finally {//释放锁lock.unlock();}}//打印10次,参数第几轮public void print10(int loop) throws InterruptedException {lock.lock();try {while(flag != 2) {c2.await();}for (int i = 1; i <=10; i++) {System.out.println(Thread.currentThread().getName()+" :: "+i+" :轮数:"+loop);}//修改标志位flag = 3;//通知CC线程c3.signal();}finally {lock.unlock();}}//打印15次,参数第几轮public void print15(int loop) throws InterruptedException {lock.lock();try {while(flag != 3) {c3.await();}for (int i = 1; i <=15; i++) {System.out.println(Thread.currentThread().getName()+" :: "+i+" :轮数:"+loop);}//修改标志位flag = 1;//通知AA线程c1.signal();}finally {lock.unlock();}}
}public class ThreadDemo3 {public static void main(String[] args) {ShareResource shareResource = new ShareResource();new Thread(()->{for (int i = 1; i <=10; i++) {try {shareResource.print5(i);} catch (InterruptedException e) {e.printStackTrace();}}},"AA").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {shareResource.print10(i);} catch (InterruptedException e) {e.printStackTrace();}}},"BB").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {shareResource.print15(i);} catch (InterruptedException e) {e.printStackTrace();}}},"CC").start();}
}
4、ReentrantLock
public class Test {private ArrayList<Integer> arrayList = new ArrayList<Integer>();public static void main(String[] args) {final Test test = new Test();new Thread() {public void run() {test.insert(Thread.currentThread());};}.start();new Thread() {public void run() {test.insert(Thread.currentThread());};}.start();}public void insert(Thread thread) {ReentrantLock lock = new ReentrantLock(); //注意这个地方lock.lock();try {System.out.println(thread.getName() + "得到了锁");for (int i = 0; i < 5; i++) {arrayList.add(i);}} catch (Exception e) {
// TODO: handle exception} finally {System.out.println(thread.getName() + "释放了锁");lock.unlock();}}
}
5、ReadWriteLock
public interface ReadWriteLock {/*** Returns the lock used for reading.** @return the lock used for reading.*/Lock readLock();/*** Returns the lock used for writing.** @return the lock used for writing.*/Lock writeLock();
}
public class Test {private ReentrantReadWriteLock rwl = newReentrantReadWriteLock();public static void main(String[] args) {final Test test = new Test();new Thread() {public void run() {test.get(Thread.currentThread());};}.start();new Thread() {public void run() {test.get(Thread.currentThread());};}.start();}public synchronized void get(Thread thread) {long start = System.currentTimeMillis();while (System.currentTimeMillis() - start <= 1) {System.out.println(thread.getName() + "正在进行读操作");}System.out.println(thread.getName() + "读操作完毕");}
}
而改成用读写锁的话:
public class Test {private ReentrantReadWriteLock rwl = newReentrantReadWriteLock();public static void main(String[] args) {final Test test = new Test();new Thread() {public void run() {test.get(Thread.currentThread());};}.start();new Thread() {public void run() {test.get(Thread.currentThread());};}.start();}public void get(Thread thread) {rwl.readLock().lock();try {long start = System.currentTimeMillis();while (System.currentTimeMillis() - start <= 1) {System.out.println(thread.getName() + "正在进行读操作");}System.out.println(thread.getName() + "读操作完毕");} finally {rwl.readLock().unlock();}}
}
== 注意: ==• 如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。• 如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
Lock 和 synchronized 有以下几点不同:
- Lock 是一个接口,而 synchronized 是 Java 中的关键字,synchronized 是内置的语言实现;
- synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而 Lock 在发生异常时,如果没有主动通过 unLock()去释放锁,则很可能造成死锁现象,因此使用 Lock 时需要在 finally 块中释放锁;
- Lock 可以让等待锁的线程响应中断,而 synchronized 却不行,使用synchronized 时,等待的线程会一直等待下去,不能够响应中断;
- 通过 Lock 可以知道有没有成功获取锁,而synchronized 却无法办到。
- Lock 可以提高多个线程进行读操作的效率。
在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时 Lock 的性能要远远优于synchronized。
相关文章:

juc概述和Lock接口
目录 一、什么是JUC 1、JUC概述 2、进程与线程 3、线程的状态 4、wait/sleep 的区别 5、并发与并行 6、管程 7、用户线程和守护线程 二、Lock接口 1、Synchronized 使用synchronized实现售票案例 使用synchronized实现增减变量操作 2、什么是 Lock 买票例子使用lo…...

图像降采样的计算原理:F.interpolate INTER_AREA
一、F.interpolate——数组采样操作 torch.nn.functional.interpolate(input, size=None, scale_factor=None, mode=nearest, align_corners=None, recompute_scale_factor=None) 功能:利用插值方法,对输入的张量数组进行上\下采样操作,换句话说就是科学合理地改变数组的尺…...

云上的甜蜜早安:腾讯云云函数助力PHP打造女友专属每日推送
用腾讯云的云函数做一个微信公众号早安,每天定时发送早安给你的女朋友! 1.首先我们登录腾讯云,在搜索栏搜索云函数 2.进入云函数,点击立即体验 3.这里我们选择 按照步骤选择 php 4.再就是配置页面,这里我们只需要配…...

Javaweb基础学习(3)
Javaweb基础学习 web核心介绍一、HTTP1.1 HTTP介绍1.2、HTTP请求数据格式1.3、HTTP响应数据格式 二、Tomcat2.1 简介2.2 基本使用2.3 Tomcat配置2.4 Tomcat部署项目2.5 Web项目结构2.6 创建Maven Web项目 三、Servlet3.1、Servlet简介&快速入门3.2 创建Servlet步骤3.3 Serv…...

使用在 Web 浏览器中运行的 VSCode 实现 ROS2 测程法
一、说明 Hadabot是软件工程师学习ROS2和机器人技术的机器人套件。我们距离Hadabot套件的测试版还有一周左右的时间。我们将在本文末尾披露有关如何注册的更多信息。 新的Hadabot套件完全支持ROS2。除了硬件套件外,Hadabot软件环境将主要基于Web浏览器,以…...

快速学习GO语言总结
备注:本博客将自己初步学习GO的总结进行分享,希望大家通过本博客可以在短时间内快速掌握GO的基本程序编码能力,如有错误请留言指正,谢谢! 一、初步了解Go语言 (一)Go语言诞生的主要问题和目标…...
尚硅谷宋红康MySQL笔记 10-18
是记录,我不会记录的特别详细 第10章 创建和管理表 标识符命名规则 数据库名、表名不得超过30个字符,变量名限制为29个只能包含 A–Z, a–z, 0–9, _共63个字符数据库名、表名、字段名等对象名中间不要包含空格同一个MySQL软件中,数据库不能…...
Java 面试题--SpringBoot篇
一、什么是 SpringBoot? Spring Boot 是 Spring 开源组织下的子项目, 是 Spring 组件一站式解决方案,主要是简化 了使用 Spring 的难度,简省了繁重 xml 的配 置,提供了各种启动器,在运行过程中自定 配置,&a…...

GitKraken 详细图文教程
前言 写这篇文章的原因是组内的产品和美术同学,开始参与到git工作流中,但是网上又没有找到一个比较详细的使用教程,所以干脆就自己写了一个[doge]。文章的内容比较基础,介绍了Git内的一些基础概念和基本操作,适合零基…...
ubuntu20.04 root用户下使用中文输入法——root用户pycharm无法用中文输入法问题
因为一些众所不周知的bug,我的pycharm使用apt或者snap安装都不行了,官网下了“绿色版”,运行pycharm.sh也运行不起来,有个java相关环境报错,jre和jdk都装了,还是有点问题,最后尝试发现可以用roo…...

FastDFS与Nginx结合搭建文件服务器,并实现公网访问【内网穿透】
文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…...

嵌入式蓝海变红海?其实是大浪淘沙!
嵌入式是当下热门的职业方向之一,吸引了众多求职者的目光。然而,有人担心大家一拥而上,导致嵌入式就业竞争激烈,找工作难度大。其实,嵌入式行业的竞争并非无法逾越的天堑,也远远没有从蓝海变成红海…...

【附安装包】Solid Edge2023安装教程最强CAD选择
软件下载 软件:Solid Edge版本:2023语言:简体中文大小:3.85G安装环境:Win11/Win10/Win8/Win7硬件要求:CPU2.0GHz 内存4G(或更高)下载通道①百度网盘丨64位下载链接:https://pan.bai…...

494. 目标和
494. 目标和 原题链接:完成情况:解题思路:数组回溯法动态规划 参考代码:数组回溯法__494目标和__动态规划 经验吸取 原题链接: 494. 目标和 https://leetcode.cn/problems/target-sum/description/ 完成情况&#…...
C++学习笔记总结练习:C++编译过程详解
编译和链接的过程 0 概述 程序要运行起来,必须要经过四个步骤:预处理、编译、汇编和链接。接下来通过几个简单的例子来详细讲解一下这些过程。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFwSfKYp-1692237034055)(imag…...

嵌入式设备应用开发(qt界面开发)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 linux界面开发有很多的方案可以选。比如说lvgl、minigui、ftk之类的。但是,这么多年来,一直屹立不倒的还是qt。相比较其他几种方案,qt支持多个平台,这里面就包括了linux平台。此…...

pytest结合Excel实现接口自动化
前言 我们先来回顾下之前篇章“pytest通过parametrize方法实现数据驱动实战”,主要是通过yaml文件来读取测试用例。而我们用Excel文件存放测试用例又有什么区别呢? 毫无疑问,Pytest自动化测试框架也能读取Excel文件实现数据驱动。 还记得之…...

【LLM数据篇】预训练数据集+指令生成sft数据集
note 在《Aligning Large Language Models with Human: A Survey》综述中对LLM数据分类为典型的人工标注数据、self-instruct数据集等优秀的开源sft数据集:alpaca_data、belle、千言数据集、firefly、moss-003-sft-data多轮对话数据集等 文章目录 note构造指令实例…...

WebDAV之π-Disk派盘 + 一羽记帐
一羽记帐是一款真正让你体验3S极速记账的轻量级APP。针对个人记账,没有花哨冗余的功能。界面美丽、无广告、极速启动、功能全面。一羽记帐功能涵括广,基本可以满足90%人的记账需求。完全无侵入、百分百无广告,无需担心数据安全,所有的操作都不经过任何第三方。 π-Disk派盘…...
ChatGPT:记一次超复杂的KVM桌面系统连接问答记录
KVM切换器可以使多台电脑共用键盘,显示器,鼠标,当电脑很多,显示器也是分为主从,需要共用键盘鼠标和音响设备,而买KVM切换器只有2个通道4进2出不满足需求时,就要组合多个KVM使用,大…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...