java基础语法(19)| 线程

前言

Hello,大家好!很开心与你们在这里相遇,我是一个喜欢文字、喜欢有趣的灵魂、喜欢探索一切有趣事物的女孩,想与你们共同学习、探索关于IT的相关知识,希望我们可以一路陪伴~

1. 多线程概述

并发与并行

  • 什么是并发

指两个或多个事件在同一个时间段内发生

  • 什么是并行

指两个或多个事件在同一时刻发生(同时发生)

 进程

是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。

线程

线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

线程调度

  • 分时调度

所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间

  • 抢占式调度  

 优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

 2. 多线程创建

 Java使用java.lang.Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用线程执行体来代表这段程序流。

 继承Thread类

继承Thread类创建并启动多线程的步骤如下:

  1. 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把run()方法称为线程执行体。

  2. 创建Thread子类的实例,即创建了线程对象

  3. 调用线程对象的start()方法来启动该线程

 定义线程类

public class MyThread extends Thread {/*** 重写run方法,完成该线程执行的逻辑*/@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println("HelloWolrd!"+i);}}
}

测试类

public class Demo01 {public static void main(String[] args) {// MyThread my = new MyThread();//这不是启动线程,相当于调了run()方法,只是普通调用// my.run();// my.run();//IllegalThreadStateException 非法的线程态态异常//为什么呢? 因为你启动两次,并不是两个线程// my.start();// my.start();MyThread my = new MyThread();MyThread my2 = new MyThread();my.start();my2.start();}
}

获取名字和设置名字

public class MyThread extends Thread{@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(getName()+" : "+i);}}
}
    public static void main(String[] args) {MyThread my = new MyThread();MyThread my2 = new MyThread();my.setName("jack");my2.setName("rose");my.start();my2.start();}

实现Runnable接口

实现Runnable接口创建并启动多线程的步骤如下:

1.定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

2.创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

3.调用线程对象的start()方法来启动线程。

 Runnable接口

public class MyRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+" : "+i);}}
}

 测试类

    public static void main(String[] args) {MyRunnable my = new MyRunnable();//起名字方式1// Thread t1 = new Thread(my,"jack");// Thread t2 = new Thread(my,"rose");Thread t1 = new Thread(my);Thread t2 = new Thread(my);//起名字方式2t1.setName("jack");t2.setName("rose");//启动线程t1.start();t2.start();}

Thread和Runnable的区别

public class ThreadTest1 implements Runnable {private int num = 10;@Overridepublic void run() {for (int i = 0; i <= 100; i++) {if (num > 0) {System.out.println(Thread.currentThread().getName()+"执行结果:" + (num--));}}}public static void main(String[] args) {ThreadTest1 t1 = new ThreadTest1();Thread t01 = new Thread(t1, "线程1");Thread t02 = new Thread(t1, "线程2");Thread t03 = new Thread(t1, "线程3");t01.start();t02.start();t03.start();}
}
public class ThreadTest2 extends Thread {private int num = 10;@Overridepublic void run() {for(int i =0; i <=100; i++) {if(num >0) {System.out.println(Thread.currentThread().getName()+"执行结果:"+(num--));}}}public static void main(String[] args) {ThreadTest2 t01 = new ThreadTest2();ThreadTest2 t02 = new ThreadTest2();ThreadTest2 t03 = new ThreadTest2();t01.start();t02.start();t03.start();}
}

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

实现Runnable接口比继承Thread类所具有的优势  

 从上面的运行结果可以看出,两者的区别。
实现Runnable接口的,对于三个线程来说共享的是ThreadTest1对象的资源。
继承Thread类,三个线程都是独立的运行,线程间不共享资源。

所以可以总结出以下区别:

1.Runnable接口的话,可以避免单继承的局限性,具有较强的健壮性。

2.Runnable可以实现资源的共享,同时处理同一资源。

3.Thread类的线程间都是独立运行的,资源不共享。

4.继承Thread类不再被其他类继承(java不存在多继承) 

3. 线程调度

方法名说明
public static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
public final void join()等待该线程终止
public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程
public final void setPriority(int newPriority)更改线程的优先级。默认为5, 最小级别:1 ,最大级别:10
public static void yield()暂停当前正在执行的线程对象,并执行其他线程。

设置线程优先级

public class ThreadPriority extends  Thread {@Overridepublic void run() {for (int i = 0; i <20 ; i++) {System.out.println(getName()+":"+i);}}
}
public class Test {public static void main(String[] args) {ThreadPriority t1 = new ThreadPriority();ThreadPriority t2 = new ThreadPriority();ThreadPriority t3 = new ThreadPriority();t1.setName("jack");t2.setName("rose");t3.setName("yiyan");// System.out.println(t1.getPriority());//5// System.out.println(t2.getPriority());//5// System.out.println(t3.getPriority());//5//参数(1-10)// t1.setPriority(0);//IllegalArgumentException 非法参数异常t1.setPriority(1);t2.setPriority(10);t3.setPriority(5);//设置优先级只是尽可以保证线程的优先级并不能完全保证,线程本身就是随机t1.start();t2.start();t3.start();}
}

线程休眠

public static void sleep(long millis) 停顿一会再走

public class Threadsleep  extends  Thread{@Overridepublic void run() {for (int i = 0; i <100 ; i++) {System.out.println(getName()+": "+i+", 日期:"+ new Date());//困了,我睡一会try {Thread.sleep(10000000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
    public static void main(String[] args) {Threadsleep t1 = new Threadsleep();Threadsleep t2 = new Threadsleep();Threadsleep t3 = new Threadsleep();t1.setName("jack");t2.setName("rose");t3.setName("yanqi");t1.start();t2.start();t3.start();}

线程的加入

public final void join():等待该线程终止。

先把加入的这个线程走完(终止)然后其他的线程自已去抢

public class ThreadJoin extends  Thread{@Overridepublic void run() {for (int i = 0; i < 100 ; i++) {System.out.println(getName()+": "+i);}}
}
public class Test {public static void main(String[] args) {ThreadJoin tj1 = new ThreadJoin();ThreadJoin tj2 = new ThreadJoin();ThreadJoin tj3 = new ThreadJoin();tj1.setName("jack");tj2.setName("rose");tj3.setName("yiyan");tj1.start();try {tj1.join();//加入线程,tj1走完之后,tj2,tj3才可以去抢} catch (InterruptedException e) {e.printStackTrace();}tj2.start();tj2.join();	tj3.start();}
}

线程礼让

public static void yield():暂停当前正在执行的线程对象,并执行其他线程。

让多个线程的执行更和谐,但是不能靠它保证一人一次。

public class ThreadYield  extends  Thread{@Overridepublic void run() {for (int i = 0; i <10 ; i++) {System.out.println(getName()+": "+ i );if(i%3==0)//线程礼让Thread.yield();}}
}
public class Test {public static void main(String[] args) {ThreadYield ty1 = new ThreadYield();ThreadYield ty2 = new ThreadYield();ThreadYield ty3 = new ThreadYield();ty1.setName("jack");ty2.setName("rose");ty1.start();ty2.start();}
}

线程守护

public final void setDaemon(boolean on):将该线程标记为守护线程、后台线程。

jvm的垃圾回收,就是一个后台线程。 该方法必须在启动线程前调用。

public class ThreadDaemon extends  Thread {d@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(getName()+": "+i);}}
}
public class Test {public static void main(String[] args) {ThreadDaemon t1 = new ThreadDaemon();ThreadDaemon t2 = new ThreadDaemon();t1.setName("关习习");t2.setName("张飞");//设置守护线程,一定在启动之前调用t1.setDaemon(true);t2.setDaemon(true);t1.start();t2.start();Thread.currentThread().setName("刘备");for (int i = 1; i <=5 ; i++) { //主线程,main方法,当前线程走到5的时候,t1,t2都会挂掉System.out.println(Thread.currentThread().getName()+": "+i);}}
}

线程停止

public final void stop():让线程停止,过时了,但是还可以使用。

public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException。

public class ThreadStop  extends  Thread{@Overridepublic void run() {System.out.println("开始执行:"+new Date());try {Thread.sleep(10000);     //睡了10秒} catch (InterruptedException e) {e.printStackTrace();}System.out.println("结果执行:"+new Date());}
}
public class Test {public static void main(String[] args) {ThreadStop t1 = new ThreadStop();t1.start();try {//如果你睡3秒还不睡醒,就干掉你Thread.sleep(3000);// t1.stop();//已过时,但可以用。如果后面还有代码就不没去运行t1.interrupt();//判断当前线程中断,不影响后面的执行} catch (InterruptedException e) {e.printStackTrace();}}
}

4. 线程安全

多线程执行的结果和单线程运行的结果是一样的,就是线程安全的。

为了保证每个线程都能正常执行原子操作,Java引入了线程同步机制。

  • ==同步代码块==

  • ==同步方法==

  • ==Lock锁==

同步代码块

synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。

 格式:

synchronized(同步锁的对象){ 需要同步操作的代码 
}

同步锁

对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁

在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着 (BLOCKED)。

  • 锁对象 可以是任意类型。

  • 多个线程对象 要使用同一把锁。

 线程类

public class RunnableImpl implements Runnable{//定义一个多个线程共享的票源private  int ticket = 100;//创建一个锁对象Object obj = new Object();//设置线程任务:卖票@Overridepublic void run() {//使用死循环,让卖票操作重复执行while(true){//同步代码块synchronized (obj){//先判断票是否存在if(ticket>0){//提高安全问题出现的概率,让程序睡眠try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}//票存在,卖票 ticket--System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");ticket--;}}}}
}

测试类

public class Demo01Ticket {public static void main(String[] args) {//创建Runnable接口的实现类对象RunnableImpl run = new RunnableImpl();//创建Thread类对象,构造方法中传递Runnable接口的实现类对象Thread t0 = new Thread(run,"窗口1");Thread t1 = new Thread(run,"窗口2");Thread t2 = new Thread(run,"窗口3");//调用start方法开启多线程t0.start();t1.start();t2.start();}
}

同步的好处和弊端

同步的好处:
   同步的出现解决了多线程的安全问题
   
同步的弊端:
     当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。

回顾: 线程安全,效率低

 同步方法

使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外 等着。

 格式

public synchronized void method(){可能会产生线程安全问题的代码 
}

同步方法中的锁是谁?

  • 对于非static方法,同步锁就是this。

  • 对于static方法,我们使用当前方法所在类的字节码对象(类名.class)。

  • synchronized关键字加到static静态方法上是给Class类上锁,而synchronized关键字加到非static静态方法上是给对象上锁(一个是对象锁,另外一个是Class锁)

public class RunnableImpl implements Runnable{//定义一个多个线程共享的票源private static int ticket = 100;//设置线程任务:卖票@Overridepublic void run() {System.out.println("this:"+this);//使用死循环,让卖票操作重复执行while(true){payTicketStatic();}}/*【静态】的同步方法锁对象是谁?不能是thisthis是创建对象之后产生的,静态方法优先于对象静态方法的锁对象是本类的class属性-->class文件对象(反射)*/public static /*synchronized*/ void payTicketStatic(){synchronized (RunnableImpl.class){//先判断票是否存在if(ticket>0){//提高安全问题出现的概率,让程序睡眠try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}//票存在,卖票 ticket--System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");ticket--;}}}/*定义一个【非静态】同步方法同步方法也会把方法内部的代码锁住只让一个线程执行同步方法的锁对象是谁?就是实现类对象 new RunnableImpl()也是就是this*/public /*synchronized*/ void payTicket(){synchronized (this){//先判断票是否存在if(ticket>0){//提高安全问题出现的概率,让程序睡眠try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}//票存在,卖票 ticket--System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");ticket--;}}}
}

Lock锁

java.util.concurrent.locks.Lock机制提供了比synchronized代码块synchronized方法更广泛的锁定操作, 同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象。

 Lock接口提供的方法

方法名说明
public void lock()加同步锁。
public void unlock()释放同步锁。
/*卖票案例出现了线程安全问题卖出了不存在的票和重复的票解决线程安全问题的三种方案:使用Lock锁java.util.concurrent.locks.Lock接口Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。Lock接口中的方法:void lock()  获取锁。void unlock()  释放锁。java.util.concurrent.locks.ReentrantLock implements Lock接口使用步骤:1.在成员位置创建一个ReentrantLock对象2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁注:如果不解锁,那么就会出现只执行一个线程的情况,体现不出多线程    */
public class RunnableImpl implements Runnable{//定义一个多个线程共享的票源private  int ticket = 100;//1.在成员位置创建一个ReentrantLock对象Lock l = new ReentrantLock();//设置线程任务:卖票@Overridepublic void run() {//使用死循环,让卖票操作重复执行while(true){//2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁l.lock();//先判断票是否存在if(ticket>0){//提高安全问题出现的概率,让程序睡眠try {Thread.sleep(10);//票存在,卖票 ticket--System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");ticket--;} catch (InterruptedException e) {e.printStackTrace();}finally {//3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁l.unlock();//无论程序是否异常,都会把锁释放}}}}
}

继承Thread类-实现卖票

继承自Thread类的线程类,要实现资源共享,在成员变量前加static,成类级别的资源了。

 同步代码块

public class MyThread extends Thread {//把当前的票源修改为staticprivate static int ticket = 100;@Overridepublic void run() {//为了卖票一直操作while (true) {//同步代码块的锁对象是其本身.classsynchronized (MyThread.class) {//判断票是否存在if (ticket > 0) {//模拟出票真实情况try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//卖票System.out.println(getName() + "-->正在卖第 " + ticket + " 张票");ticket--;}}}}
}
public static void main(String[] args) {MyThread my1 = new MyThread();MyThread my2 = new MyThread();MyThread my3 = new MyThread();my1.setName("窗口1");my2.setName("窗口2");my3.setName("窗口3");my1.start();my2.start();my3.start();}

同步方法

public class MyThread extends Thread {//把当前的票源修改为staticprivate static int ticket = 100;@Overridepublic void run() {//为了卖票一直操作while (true) {payTic();}}//继承thread类的同步方法,只能是静态private static synchronized void payTic() {//判断票是否存在if (ticket > 0) {//模拟出票真实情况try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//卖票System.out.println(Thread.currentThread().getName() + "-->正在卖第 " + ticket + " 张票");ticket--;}}
}
public static void main(String[] args) {MyThread my1 = new MyThread();MyThread my2 = new MyThread();MyThread my3 = new MyThread();my1.setName("窗口1");my2.setName("窗口2");my3.setName("窗口3");my1.start();my2.start();my3.start();}

Lock方法

package cn.yanqi_06;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class MyThread extends Thread {//把当前的票源修改为staticprivate static int ticket = 100;//继承Trhead类的lock锁一定是静态的private static Lock l = new ReentrantLock();@Overridepublic void run() {//为了卖票一直操作while (true) {l.lock();//判断票是否存在if (ticket > 0) {//模拟出票真实情况try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//卖票System.out.println(Thread.currentThread().getName() + "-->正在卖第 " + ticket + " 张票");ticket--;}l.unlock();}}
}
public static void main(String[] args) {MyThread my1 = new MyThread();MyThread my2 = new MyThread();MyThread my3 = new MyThread();my1.setName("窗口1");my2.setName("窗口2");my3.setName("窗口3");my1.start();my2.start();my3.start();}

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

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

相关文章

[Linux - C] 自主Shell

[Linux - C] 自主Shell [Linux - C语言] 自主Shell逻辑策划 main()打印命令行 void MakeCommandLineAndPrint()用户名 USER主机名 HOSTNAME当前目录 PWDSkipPath 切割目录打印命令行 获取用户字符串 int GetUserCommand()检查重定向 void CheckRedir()切割字符 void SplitComma…

数据加密、文档加密为什么都选择安企神软件

数据加密、文档加密为什么都选择安企神软件 免费试用安企神 在数据加密和文件加密领域&#xff0c;有众多优秀的软件&#xff0c;他们功能各异、价格不同、效果也大相径庭&#xff0c;经过对比使用、用户口碑和技术网站评判&#xff0c;安企神在各方面都稳坐第一把交易。其原…

新闻媒体行业邮件推广:精准推送,创造价值

在当今信息爆炸的时代&#xff0c;新闻行业如何在竞争激烈的市场中脱颖而出&#xff0c;吸引读者的目光&#xff0c;成为了每个新闻机构都需要认真思考的问题。许可式邮件营销成为了一种强大的工具&#xff0c;不仅能够向订阅者发送新闻期刊&#xff0c;还能够向广告商发送宣传…

【基础物理实验】【AFM虚拟实验】基于AFM的物质表面微观结构及力学性质表征仿真实验(下)【北京航空航天大学】

本次实验&#xff08;上&#xff09;见博客&#xff1a;【基础物理实验】【AFM虚拟实验】基于AFM的物质表面微观结构及力学性质表征仿真实验&#xff08;上&#xff09;【北京航空航天大学】 本次实验&#xff08;中&#xff09;见博客&#xff1a;【基础物理实验】【AFM虚拟实…

LLamaSharp加载llama.cpp转化好的模型

新建.net8控制台项目 安装依赖包 LLamaSharp和LLamaSharp.Backend.Cpu 准备好转化好的模型 没有的话参考这篇文章https://blog.csdn.net/qq_36437991/article/details/137248622 编写代码 using LLama; using LLama.Common; using LLama.Native;namespace llamasharpstu…

N皇后问题(DFS解决)

文章目录 一、题目分析二、对角线判断&#xff08;分两种&#xff09;三、代码演示 先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;^ _ ^<3 ❤️ ❤️ ❤️ 码字不易&#xff0c;大家的支持就是我坚持下去的动力。点赞后不要忘了关注我哦&#xff01; 一…

全球7大指纹浏览器排行榜:哪个最适合你?

在数字时代&#xff0c;我们每一次上网都会留下独特的数字足迹&#xff0c;被称为“浏览器指纹”。为了保护这些私人信息不被滥用&#xff0c;指纹浏览器成为了一个重要工具。但是&#xff0c;并非所有的指纹浏览器都是一样的&#xff0c;它们各有特点&#xff0c;适用于不同的…

数字乡村创新实践探索农业现代化路径:科技赋能农业产业升级、提升乡村治理效能与农民幸福感

随着信息技术的快速发展和数字化时代的到来&#xff0c;数字乡村建设正成为推动农业现代化、提升农业产业竞争力、优化乡村治理以及提高农民幸福感的重要途径。本文将围绕数字乡村创新实践&#xff0c;探讨其在农业现代化路径中的积极作用&#xff0c;以及如何通过科技赋能实现…

28. 找出字符串中第一个匹配项的下标(KMP)

class Solution {public int[] getNext(int[] next,String s){//j有两层含义&#xff1a;&#xff08;1&#xff09;最长公共前后缀的长度&#xff08;2&#xff09;前缀的末尾&#xff0c;是即将匹配的那个位置int j 0;//i含义&#xff1a;后缀的末尾&#xff0c;是即将匹配的…

Python疑难杂症(20)---介绍Python的pandas模块中将数据导入内存和导出数据的方法,以及一些参数的用法。

Python的pandas模块中数据框这种数据类型&#xff0c;可以通过文件导入函数&#xff0c;将磁盘上的csv、execl等类型的文件装入内存&#xff0c;并生成数据框的格式&#xff0c;以方便后续使用pandas的专有方法进行处理。 6、DataFrame数据输导入导出方法 Pandas常用的读取数…

安装ps提示MSVCP140.dll丢失怎么办,推荐几种有效的解决方法

在成功完成Adobe Photoshop&#xff08;简称PS&#xff09;软件的安装过程之后&#xff0c;当用户试图启动并运行该程序时&#xff0c;系统却弹出了一个令人困扰的错误提示信息&#xff0c;明确指出&#xff1a;“无法找到MSVCP140.dll”这一关键文件。这意味着尽管PS软件已经成…

redmibook 14 2020 安装 ubuntu

1. 参考博客 # Ubuntu20.10系统安装 -- 小米redmibook pro14 https://zhuanlan.zhihu.com/p/616543561# ubuntu18.04 wifi 问题 https://blog.csdn.net/u012748494/article/details/105421656/# 笔记本电脑安装了Ubuntu系统设置关盖/合盖不挂起/不睡眠 https://blog.csdn.net/…

权威Scrum敏捷开发企业级实训/敏捷开发培训课程

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架。 这是一个两天的实训课程&#xff0c;面向研发管理者、项目经理、产品经理、研发团队等&#xff0c;旨在帮助学员全面系统地学习Scrum和敏捷开发, 帮助企业快速启动敏…

【机器学习】科学库使用第5篇:Matplotlib,学习目标【附代码文档】

机器学习&#xff08;科学计算库&#xff09;完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;机器学习&#xff08;常用科学计算库的使用&#xff09;基础定位、目标&#xff0c;机器学习概述定位,目标,学习目标,学习目标,1 人工智能应用场景,2 人工智能小…

【网络设备巡检命令】--思科、华为、H3C、锐捷

【网络设备巡检命令】--思科、华为、H3C、锐捷 一、思科二、华为三、H3C四、锐捷 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 一、思科 1、查看系统信息&#xff1a; show version2、查看时间&#xff1a; show clock3、查看序列号&a…

Nginx内存池相关源码剖析(三)小块内存分配逻辑

在Nginx中&#xff0c;小块内存通常指的是那些大小相对较小、分配和释放频率较高的内存块。这些内存块由于数量众多、管理复杂&#xff0c;因此需要使用一种高效的内存管理机制来减少内存管理的开销和内存碎片的产生。 Nginx内存池通过一种预分配和复用的方式来管理小块内存。当…

觉飞、希亦、Daily neaty内衣洗衣机好用吗?爆款产品性能全面测评!

近几年来小家电产品中&#xff0c;内衣洗衣机的讨论热度无疑是最大的&#xff0c;功能多、操作方便&#xff0c;用内衣洗衣机来清洗内衣裤会更加卫生和安全&#xff0c;能满足了消费者的多种需求。不过尽管市面上的内衣洗衣机品牌很多、挑选空间大&#xff0c;也不是所有产品都…

RT-thread-线程间通讯3-事件集

事件集 事件集也是线程间同步的机制之一,一个事件集可以包含多个事件,利用事件集可以完成一对多,多对多的线程间同步。 一个线程和多个事件的关系可设置为: 其中任意一个事件唤醒 线程,或几个事件都到达后唤醒线程,多个事件集合可以用一个32bit无符号整型变量来表示,…

4.8-4.12算法刷题笔记

刷题 堆1. 堆排序2. 模拟堆 哈希表3. 模拟散列表4. 字符串哈希 DFS5. 排列数字6. n-皇后问题 2. BFS&#xff08;队列&#xff09;7. 字母迷宫8. 滑动谜题 3. 树与图的dfs9. 树的重心 4. 树与图的bfs(最短路)10. 图中点的层次( 无权最短路 ) 5. 拓扑排序11. 课程表 6. 朴素dijk…

docker (CentOS,ubuntu)安装及常用命令

Docker和虚拟机一样&#xff0c;都拥有环境隔离的能力&#xff0c;但它比虚拟机更加轻量级&#xff0c;可以使资源更大化地得到应用 Client&#xff08;Docker客户端&#xff09;&#xff1a;是Docker的用户界面&#xff0c;可以接受用户命令&#xff08;docker build&#xff…