JAVA小白学习日记Day10

1.线程锁

使用Runnable接口和Lambda表达式:

在 EasyThreadA 类的 mainA 方法中,通过创建 Runnable 实例 run,并使用Lambda表达式。 EasyThreadA::method 绑定到 run 上。然后创建两个线程 a 和 b,分别启动它们,它们会并发地执行 method 方法向共享的 list 中添加元素。这里的 list 是一个静态的 ArrayList,可能存在线程安全问题。
继承Thread类:

ThreadA 类继承自 Thread 类,重写了 run 方法,在其中向自己的 list 中添加元素。在 mainB 方法中创建了两个 ThreadA 实例 a 和 b,启动它们分别执行。每个线程拥有独立的 list,不存在直接的线程安全问题。
实现Runnable接口:

RunA 类实现了 Runnable 接口,在 run 方法中也向自己的 list 中添加元素。在 main 方法中创建了两个 RunA 实例作为 Thread 的任务,分别启动它们。每个 RunA 实例拥有独立的 list,不存在直接的线程安全问题。
需要注意的知识点:
多线程的实现方式:

可以通过实现 Runnable 接口或者继承 Thread 类来创建线程。推荐优先使用实现 Runnable 接口,因为Java中类只能单继承,而实现接口可以更灵活地组合多个接口实现不同的功能。
线程同步和等待:

使用 Thread.sleep(1000) 来模拟线程执行过程中的等待时间。在实际应用中,需要根据具体需求使用合适的线程同步机制,如 synchronized 关键字、Lock 接口、Atomic 类等来确保线程安全性。
Lambda表达式:

在 mainA 方法中使用了Lambda表达式 EasyThreadA::method,简化了匿名内部类的写法,提升了代码的简洁性和可读性。

package com.easy725;import java.util.ArrayList;
import java.util.List;public class EasyThreadA {static List list=new ArrayList();public static void method(){for (int i = 0; i <10 ; i++) {list.add(i+"A"+Thread.currentThread().getName());}}public static void mainA(String[] args) {Runnable run=EasyThreadA::method;Thread a=new Thread(run);Thread b=new Thread(run);a.start();b.start();try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(list.size());}public static void mainB(String[] args) {ThreadA a=new ThreadA();ThreadA b=new ThreadA();a.start();b.start();try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(a.list);System.out.println(b.list);}public static void main(String[] args) {RunA run=new RunA();Thread a=new Thread(run);Thread b=new Thread(run);a.start();b.start();try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(run.list.size());}}
class ThreadA extends Thread{public List list=new ArrayList();@Overridepublic void run() {for (int i = 0; i <10 ; i++) {list.add("a");}}
}
class RunA implements Runnable{public List list=new ArrayList();@Overridepublic void run() {for (int i = 0; i <10 ; i++) {list.add("a");}}
}

Lock对象的创建和使用:

Lock lock = new ReentrantLock();:创建了一个 ReentrantLock 类型的锁对象 lock。ReentrantLock 是可重入锁,支持公平和非公平性选择,默认是非公平锁(false)。

public void method() 方法中的逻辑:
if (lock.tryLock()) {:尝试获取锁。如果获取成功(返回 true),否则打印当前线程名并输出 "进入方法",然后输出 "结束方法",最后解锁 lock。
else {:如果尝试加锁失败,输出 "加锁未成功-----去执行别的代码",然后通过 Thread.sleep(1000) 模拟执行其他代码的情况,随后递归调用 method() 方法再次尝试获取锁。
main方法中的线程创建和启动:

Runnable run = new EasyThreadB()::method;:创建一个 Runnable 实例,通过方法引用绑定到 EasyThreadB 的 method() 方法上。
Thread a = new Thread(run); 和 Thread b = new Thread(run);:创建两个线程 a 和 b,它们共享同一个 run 实例,即同一个 method() 方法。
a.start(); 和 b.start();:启动两个线程并发执行 method() 方法。
需要注意的知识点:
Lock接口与ReentrantLock类:

Lock 接口提供了比传统的 synchronized 块和方法更广泛的锁定操作。ReentrantLock 是 Lock 接口的实现类,具有可重入特性,允许线程在同一个线程中多次获取同一个锁,避免死锁情况。
tryLock() 方法是 Lock 接口的一部分,尝试获取锁,如果成功则返回 true,否则立即返回 false,不会阻塞线程。这在避免线程长时间等待锁的情况下很有用。最后要unLock()方法解锁。
多线程同步与并发控制:

使用 ReentrantLock 可以更精确地控制多线程的并发访问,可以在需要的时候尝试获取锁,也可以实现公平性或非公平性的锁分配策略。
锁的释放应该始终放在 try 块的 finally 块中,以确保即使在获取锁期间发生异常,锁也能够被安全地释放。

死锁:

进程死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

线程死锁是指由于两个或者两个以上的线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。

死锁的产生还涉及到一些具体的条件,这些条件可以被看作是死锁产生的必要条件,包括:

互斥条件:资源不能被多个进程或线程同时访问,即资源是互斥的。
请求保持条件:进程或线程在请求资源时,已经持有其他资源,并且不愿意释放已经持有的资源。
不可剥夺条件:已经分配给进程或线程的资源,在未使用完之前不能被其他进程或线程剥夺。
循环等待条件:多个进程或线程之间形成一个循环等待链,每个进程或线程都在等待链中下一个进程或线程释放资源。

package com.easy725;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class EasyThreadB {//锁对象  LockLock lock=new ReentrantLock();//创建锁对象,在()中选择是否是公平锁,默认false(非公平锁)。public void method(){//lock.lock();//加锁//lock.trylock()  尝试加锁,加锁成功返回true,失败返回false。if (lock.tryLock()) {System.out.println(Thread.currentThread().getName() + "进入方法");System.out.println(Thread.currentThread().getName() + "结束方法");lock.unlock();//解锁}else {System.out.println("加锁未成功-----去执行别的代码");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}method();}}public static void main(String[] args) {Runnable run=new EasyThreadB()::method;Thread a=new Thread(run);Thread b=new Thread(run);a.start();b.start();}
}

读写锁 (ReentrantReadWriteLock):
ReentrantReadWriteLock 是一个锁容器,包含了读锁和写锁,能够提供比普通的互斥锁(如 ReentrantLock)更高的并发性。
读锁允许多个线程同时获取,适合对共享资源进行读取操作。
写锁是排他的,只允许一个线程获取,用于对共享资源进行写操作。
在代码中,通过 rrwl.readLock() 获取读锁,通过 rrwl.writeLock() 获取写锁,确保对共享资源的安全访问。

线程的启动和执行:
使用 Thread 类和 Runnable 接口创建多线程,通过 Thread.start() 启动线程,实现并发执行多个方法。
在 main 方法中,创建了多个读线程和写线程,分别调用 method() 和 methodWrite() 方法。
线程同步和锁的释放:
使用 lock.lock() 和 lock.unlock() 进行锁的获取和释放,确保在多线程环境下对共享资源的安全访问。
一般使用 try-finally 块确保在出现异常时能够正确释放锁,避免死锁或资源泄漏问题。

package com.easy725;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class EasyThreadC {//ReentrantReadWriteLock是个锁容器public static ReentrantReadWriteLock rrwl=new ReentrantReadWriteLock();public static ReentrantLock rl=new ReentrantLock();public static void method(){System.out.println(Thread.currentThread().getName()+"进入方法");Lock lock= rrwl.readLock();lock.lock();System.out.println(Thread.currentThread().getName()+"加锁成功----读锁");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"方法结束");lock.unlock();}public static void methodWrite(){System.out.println(Thread.currentThread().getName()+"进入方法");Lock lock= rrwl.writeLock();lock.lock();System.out.println(Thread.currentThread().getName()+"加锁成功----写锁");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"方法结束");lock.unlock();}public static void main(String[] args) {Runnable run=EasyThreadC::method;Runnable runWrite=EasyThreadC::methodWrite;Thread a=new Thread(run);a.start();Thread b=new Thread(run);b.start();Thread c=new Thread(run);c.start();Thread d=new Thread(run);d.start();Thread e=new Thread(run);e.start();Thread f=new Thread(runWrite);f.start();Thread g=new Thread(runWrite);g.start();Thread h=new Thread(runWrite);h.start();Thread i=new Thread(runWrite);i.start();System.out.println("main线程结束");}
}

同步和对象锁
synchronized 同步块:使用 synchronized (OBJ) 对象锁,确保多个线程在访问共享资源时的安全性。
wait 和 notify:通过 OBJ.wait() 和 OBJ.notify() 方法实现线程的等待和唤醒机制。
wait():使当前线程进入等待状态,并释放对象锁,直到其他线程调用对象的 notify() 或 notifyAll() 方法唤醒它。
notify() 和 notifyAll():唤醒等待在该对象上的一个或多个线程,使它们从等待池中进入就绪状态。
线程生命周期和状态
线程等待和重新运行:展示了线程如何在 wait() 被调用后进入等待状态,并在被唤醒后重新运行。
wait和sleep的区别:
wait是Object中定义的方法,可以由锁对象调用,让执行到该代码的线程进入到等待状态。
sleep是Thread类中定义的静态方法,也可以让执行到该行的线程进入等待状态。
区别:
1.sleep需要传入一个毫秒数,到达时间后会自动唤醒。wait不能自动唤醒,必须调用notify或者notifyALL方法。
2.sleep方法保持锁状态进入等待状态。wait方法会解除锁状态,其他线程可以进入运行。

package com.easy725;public class EasyThreadD {public static final Object OBJ =new Object();public static void method(){System.out.println(Thread.currentThread().getName()+"进入方法");synchronized (OBJ){OBJ.notify();//唤醒一条被该锁对象wait的线程//OBJ.notifyAll();//唤醒全部被锁对象wait的线程System.out.println(Thread.currentThread().getName()+"进入同步代码块");try {try {System.out.println(Thread.currentThread().getName()+"进入等待状态");OBJ.wait();//让执行到改代码的线程进入到等待状态,在等待池中。System.out.println(Thread.currentThread().getName()+"重新运行");} catch (InterruptedException e) {e.printStackTrace();}Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"结束同步代码块");OBJ.notify();}}public static void main(String[] args) {Runnable run = EasyThreadD::method;Thread a=new Thread(run);a.start();Thread b=new Thread(run);b.start();Thread c=new Thread(run);c.start();Thread d=new Thread(run);d.start();}//wait和sleep的区别://wait是Object中定义的方法,可以由锁对象调用,让执行到该代码的线程进入到等待状态。//sleep是Thread类中定义的静态方法,也可以让执行到该行的线程进入等待状态。//区别://1.sleep需要传入一个毫秒数,到达时间后会自动唤醒。wait不能自动唤醒,必须调用notify或者notifyALL方法。//2.sleep方法保持锁状态进入等待状态。wait方法会解除锁状态,其他线程可以进入运行。
}

2.线程池

线程池:

ThreadPoolExecutor 是 Java 中用于管理线程池的类,通过它可以有效地重用线程,完成线程的创建管理和销毁工作。
在代码中,通过 ThreadPoolExecutor 的构造方法创建了一个线程池 tpe。
在这里,使用了一个 ArrayBlockingQueue 作为任务队列 qu,它限制了队列的容量为 12。
任务提交与执行:

线程池可以执行两种类型的任务:Runnable 和 Callable。
Runnable run = EasyExecuters::method; 定义了一个简单的 Runnable 任务,它会调用 method 方法。
tpe.execute(run); 提交 run 任务给线程池执行。
Callable<String> call = EasyExecuters::methodCall; 定义了一个 Callable 任务,它会调用 methodCall 方法,并返回一个结果。
Future<String> f = tpe.submit(call); 提交 call 任务给线程池执行,并获取一个 Future 对象,用于获取任务的执行结果。
任务执行结果获取:

System.out.println(f.get()); 使用 Future 对象的 get() 方法来获取 call 任务的执行结果。这是一个阻塞方法,会等待任务执行完毕并返回结果。
线程池的关闭:

tpe.shutdown(); 调用 shutdown() 方法关闭线程池。这会使线程池停止接受新的任务,并尝试将现有的任务执行完毕后关闭。

package com.easy725;import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.*;public class EasyExecuters {//线程池   池==重用//完成线程创建,管理,销毁工作public static void main(String[] args) throws ExecutionException, InterruptedException {BlockingQueue qu = new ArrayBlockingQueue(12);ThreadPoolExecutor tpe=new ThreadPoolExecutor(5,10,10,TimeUnit.SECONDS,qu,Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());//线程任务:Runnable,CallableRunnable run=EasyExecuters::method;tpe.execute(run);Callable<String> call=EasyExecuters::methodCall;Future<String> f=tpe.submit(call);//f.cancel(true);//是否取消任务,一种中断线程的方式//tpe.submit(run);System.out.println(f.get());//会等待线程执行完毕//关闭线程池对象tpe.shutdown();}public static void method(){System.out.println(Thread.currentThread().getName()+"执行代码");}public static String methodCall(){System.out.println(Thread.currentThread().getName()+"执行代码call");return "callResult";}
}

1. 线程池的七个参数解释
在代码中,通过 ThreadPoolExecutor 的构造方法指定了以下七个参数:

corePoolSize: 核心线程数,即线程池中保持活跃的线程数量,即使它们是空闲的也会保留在池中。
maximumPoolSize: 最大线程数,线程池中允许的最大线程数量。当活跃线程数达到核心线程数,并且工作队列已满时,会创建新的线程,直到达到这个最大值。
keepAliveTime: 空闲线程的存活时间。超过核心线程数的线程在空闲超过这个时间后会被销毁,直到线程池的大小重新变为核心线程数为止。
unit: keepAliveTime 的时间单位。
workQueue: 工作队列,用于保存等待执行的任务。在本例中使用了 ArrayBlockingQueue,其容量为 12。
threadFactory: 线程工厂,用于创建新线程。
handler: 回绝策略,用于处理无法执行的任务。在本例中使用了 DiscardPolicy,即直接丢弃新任务而不抛出异常。

2.四种回绝策略(可以自定义)
AbortPolicy(默认):放弃该任务并会抛出一个异常,RejectedExecutionException。
CallerRunsPolicy:调用者执行,让传递任务的线程执行此任务。
DiscardOldestPolicy:放弃队列中时间最长的任务,不会抛出异常。
DiscardPolicy:直接放弃新的任务,不会抛异常。


3. 线程池的工作原理
当任务提交给线程池时,线程池会按照以下步骤处理任务:
如果当前活跃线程数小于核心线程数,创建新的线程来执行任务。
如果当前活跃线程数等于核心线程数,将任务加入工作队列。
如果工作队列已满但未达到最大线程数,创建新线程来执行任务。(占最大线程数)
如果工作队列已满且线程数已达到最大值,执行指定的回绝策略来处理新任务。


4. 内置的线程池对象
Java 提供了几种常见的内置线程池对象,可以根据应用的需要选择合适的线程池:

Executors.newCachedThreadPool(): 可根据需要(没有空闲就创建新线程)的线程池,空闲线程会在 60 秒后被回收。
Executors.newFixedThreadPool(int n): 固定大小的线程池,可以控制最大线程数。
Executors.newScheduledThreadPool(int corePoolSize): 支持定时和周期性的处理方案。
Executors.newSingleThreadExecutor(): 只有一个线程的线程池,确保所有任务按顺序执行。


5. 任务执行与线程池关闭
在代码中,通过 execute() 方法提交 Runnable 任务给线程池执行。
最后调用 shutdown() 方法关闭线程池,这会使线程池停止接受新任务,并尝试将已有的任务执行完毕后关闭。

package com.easy725;import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.*;public class EasyExecutersA {public static void main(String[] args) {//1.说明线程池的七个参数//2.四种回绝策略(可以自定义)//AbortPolicy(默认):放弃该任务并会抛出一个异常,RejectedExecutionException。//CallerRunsPolicy:调用者执行,让传递任务的线程执行此任务。//DiscardOldestPolicy:放弃队列中时间最长的任务,不会抛出异常。//DiscardPolicy:直接放弃新的任务,不会抛异常。//3.线程池的工作原理://  任务放置在工作队列中//1>池中是否有空闲的线程,如果有,让该线程执行任务。//2>如果池中没有空闲的线程,判断线程数量是否达到核心线程数。//3>如果没有达到,创建新的线程执行任务,直到填满核心数。如果已经达到,优先在队列中存储,直到队列填满。//4>工作队列填满之后再添加新的任务,判断是否达到最大线程数,如果没有,创建新的线程执行任务,直到填满最大线程数。//5>如果填满最大线程数,队列也已经填满,没有空闲的线程,就执行回绝策略。//线程池中的线程达到(超过)核心线程数,超出的数量会根据存活时间进行销毁。直到数量达到核心线程数。如果线程的数量少于核心线程数,不会消亡。//java中内置的线程池对象//可以根据工作任务创建线程,如果没有空闲的线程,就创建新的线程。线程存活时间60s。//Executors.newCachedThreadPool();//设定最大线程数量//Executors.newFixedThreadPool(10);//提供定时运行的处理方案//Executors.newScheduledThreadPool(10);//创建一个具有单个线程的线程池,保证任务队列完全按照顺序执行//Executors.newSingleThreadExecutor();BlockingQueue queue=new ArrayBlockingQueue(12);ThreadPoolExecutor tpe=new ThreadPoolExecutor(5,8,10,TimeUnit.SECONDS,queue,Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());Runnable run =()->{System.out.println(Thread.currentThread().getName()+"执行run方法");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"执行结束");};for (int i = 0; i <21 ; i++) {tpe.execute(run);}tpe.shutdown();}
}

3.枚举

枚举类 默认继承Enum类
首行必须枚举所有的实例。Enum的实例是可比较的(根据实例出来的顺序)。但是不可序列化,不能被new,克隆等操作。
当枚举中只有一个实例时,这个类就是单例的。

package com.easy725;public enum  EasyColor {//枚举类 默认继承Enum类//首行必须枚举所有的实例。Enum的实例是可比较的(根据实例出来的顺序)。但是不可序列化,不能被new,克隆等操作。//当枚举中只有一个实例时,这个类就是单例的。RED,YELLOW,GREEN,BLUE,PINK;public void printColor(){System.out.println(this.name());System.out.println(this.ordinal());}}
class Test{public static void main(String[] args) {EasyColor.PINK.printColor();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/51766.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NebulaGraph图数据库使用教程

一、NebulaGraph 是什么&#xff1f; NebulaGraph 是一款开源的图数据库&#xff0c;擅长处理千亿个顶点和万亿条边的超大规模数据集。 NebulaGraph 社区已成长为一个荟聚了众多用户、融合了各类图技术场景实践知识的活跃开源社区。你可以在其中与大家共同交流 NebulaGraph 周…

音视频开发入门很难?可能是你姿势不对

作为程序员&#xff0c;听到最烦的两个词一个是bug&#xff0c;在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「音视频开发的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大…

深度学习之优化器(简要总结)

优化器是用于训练神经网络模型的关键组件&#xff0c;它们决定了模型参数如何根据损失函数的梯度进行更新。不同的优化器具有不同的特性和适用场景。 下面将介绍几种常见的深度学习优化器&#xff0c;以及基于pytorch版本的定义和使用方法。 1.SGD&#xff08;Stochastic Gra…

【书生大模型实战】L1-书生大模型全链路开源体系

一、关卡任务 观看本关卡视频后&#xff0c;写一篇关于书生大模型全链路开源开放体系的笔记。 视频链接&#xff1a;【书生浦语大模型全链路开源体系】 https://www.bilibili.com/video/BV1Vx421X72D/?share_sourcecopy_web 二、实验过程 书生浦语大模型全链路开源体系&am…

JavaScript字符串转换成base64编码方法

// base64编码表 const base64EncodeChars ref<string>("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/" );/*** base64编码* param {Object} str*/ const base64encode (str: string) > {let result "";// 循环遍历字符串…

银行贷款信用评分不足?大数据帮你找回失去的“分”

在这个信息爆炸的时代&#xff0c;无论是个人还是企业&#xff0c;数据都成为了衡量信用和评估风险的重要依据。贷款、融资、求职甚至是日常消费&#xff0c;都可能因为一份好的数据报告而变得更加顺畅。那么&#xff0c;如何高效地查询自己的大数据&#xff0c;面对评分不足时…

Typescript配置文件(tsconfig.json)详解系列五:allowArbitraryExtensions

前言 本文使用的Typescript版本为5.5.2 配置 {compilerOptions: {"allowArbitraryExtensions": true} }说明 allowArbitraryExtensions是typescript5.x后加入的字段&#xff0c;允许我们可以导入任何后缀名的文件。 并且我们必须要有一个和这个文件配套的类型声明…

【持续集成_02课_Jenkins+Git+Gogs综合应用】

https://www.cnblogs.com/xfeiyun/p/17510472.html Jenkins部署及持续集成——傻瓜式教程-腾讯云开发者社区-腾讯云 一、Jenkins安装 Jenkins由Java语言编写而成&#xff0c;安装包即是一个war包。因此&#xff0c;Jenkins的运行启动依赖于Java环境&#xff0c;同时&#xf…

G120 EPos配置方案及应用场景

EPos功能就是基本定位器功能,它可计算出轴的运行特性,使轴以时间最佳的方式移动到目标位置。EPos功能主要包括:设定值 直接给定(MDI)功能、 选择程序段功能、回参考点功能、点动功能、运行到固定挡块功能。 EPos功能通过处理给定的加速度、速度和位置值生成运行特性曲线,…

正则采集器之四——采集网站管理

本文介绍正则采集器的采集网站管理的开发。 系统需要动态添加采集网站&#xff0c;对网站地址、名称、匹配商品的正则表达式字段进行设置。 新建数据库表 CREATE TABLE item_website (id bigint NOT NULL AUTO_INCREMENT,code varchar(16) CHARACTER SET utf8mb4 COLLATE ut…

springbootsecurity整合thymeleaf

首先创建一个springboot项目 然后加入相关依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&q…

昇思 25 天学习打卡营第 15 天 | mindspore 实现 VisionTransformer 图像分类

1. 背景&#xff1a; 使用 mindspore 学习神经网络&#xff0c;打卡第 15 天&#xff1b;主要内容也依据 mindspore 的学习记录。 2. Vision Transformer 介绍&#xff1a; mindspore 实现 VisionTransformer 图像分类&#xff1b;VisionTransformer 论文地址 VisionTransfo…

深入分析MiniQMT实时订阅延迟测试代码

摘要 本文将深入分析两段MiniQMT平台的Python代码&#xff0c;这些代码用于测试实时数据订阅的延迟情况。我们将详细探讨代码的结构、关键功能以及它们在实时交易策略中的应用&#xff0c;并通过代码示例展示其工作原理。 背景介绍 MiniQMT是一个量化交易平台&#xff0c;支…

Redis是多线程还是单线程?

文章目录 1、用户态和内核态2、阻塞IO3、非阻塞IO4、IO多路复用4.1 select4.2 poll4.3 epoll4.4 epoll中的ET和LT4.5 epoll的服务端流程 5、信号驱动6、异步IO7、对比8、Redis是单线程的吗&#xff1f;9、单线程多线程网络模型变更 1、用户态和内核态 1、ubuntu和Centos 都是Li…

KADB heap表VS AO表插入数据测试

单条插入数据准备&#xff1a; test# \d test Table "public.test" Column | Type | Modifiers ------------------------------------------ a | integer | b | character varying(20) | Distributed by: (a) test# in…

day 02

作业&#xff1a; 1> 写一个日志文件&#xff0c;将程序启动后&#xff0c;每一秒的时间写入到文件中 1、2024- 7-29 10:31:19 2、2024- 7-29 10:31:20 3、2024- 7-29 10:31:21 ctrlc:停止程序 ./a.out 4、2024- 7-29 10:35:06 5、2024- 7-29 10:35:07 6、2024- 7-29 10:3…

轻松入门Linux—CentOS,直接拿捏 —/— <2>

一 、权限问题详细讲解 读写的权限可以分别写成 r, w, x 总共有九个权限&#xff0c;可以分组三大组分别是&#xff1a; user&#xff1a;当前文件所属用户的权限 group&#xff1a;与当前文件所属用户同一组的用户权限 others&#xff1a;其他用户的权限 故使用 u, g, o 来代表…

从装机到冯·诺依曼架构,揭秘计算机的硬件组成

在当今数字化的时代&#xff0c;计算机已经成为我们生活和工作中不可或缺的一部分。从日常办公到科学计算&#xff0c;从畅玩游戏到无人驾驶&#xff0c;计算机简直无所不能。而这一切的背后&#xff0c;离不开其精密而复杂的硬件组成。今天&#xff0c;我们将一起探索计算机的…

Java中的异常总结

异常的基本概念 异常&#xff08;Exception&#xff09;&#xff1a;表示程序在执行过程中出现的错误或异常情况。异常通常表示程序的非正常状态&#xff0c;需要处理以防止程序崩溃。错误&#xff08;Error&#xff09;&#xff1a;表示虚拟机出现的严重问题&#xff0c;通常…

Selenium Java中的isDisplayed()方法

isDisplayed&#xff08;&#xff09;方法用于确定元素是否可见。本文将详细讨论 的WebElement接口isDisplayed&#xff08;&#xff09;方法。 方法声明- boolean isDisplayed&#xff08;&#xff09;它能做什么&#xff1f;此方法用于判断元素是否显示。这个方法节省了我们…