Java学习31-Java 多线程Thread 线程的创建

多线程的概念:

用户想要一边听歌,一边QQ聊天,一边游戏。要求能并发执行。

  • program程序: 有特殊功能的一组代码
  • process进程: 正在执行中的program,或者程序program的一次执行过程
  • thread线程:程序program内部的一条执行路经,一个process至少有一个thread,一个process同一时间若并行执行多个thread,就是支持多线程的。

一个process中的多个thread共享相同的内存单元,他们从同一个堆中分配对象,可以访问相同的变量和对象,但是多个thread操作共享的系统资源可能就会带来安全的隐患。注意:不同的进程之间是不共享内存的;进程之间的数据交换和通信成本很高;

如图所示,下面的红框左侧Method Area和Heap就是共享的,浅蓝色的Virtual Machine Stack, Native Method Stack, Program Counter Register是每个thread运行时自己独有的。

Thread调度

  • 分时调度: CPU给大家平均每个thread分多久时间,均分时间。
  • 抢占式调度: 让优先级高的以较大概率优先使用CPU,如果thread们优先级相同,那就随机选择一个,Java用的就这种。

并行parallel和并发concurrency

并行 parallel:两个或多个事件在同一时刻同时发生。同一时刻,有多条指令多个CPU同时执行,相当于“多个人同时干不同的活”。

parallel
并发 concurrency:两个或多个事件在同一时间发生。在一段时间内,有多条指令单个CPU快速轮换,交替执行,使得在宏观上看起来具有多个进程同时执行的效果。相当于“一个人不停的干不同的活”。
concurrency

如何创建线程

两种办法
多线程的创建方式一:自建类继承Thread类,用户重写run方法
多线程的创建方式二:用户创建实现Runnable接口的类,再在里面重写run方法

(java.lang.Thread类是线程类,所有的线程对象都必须是Thread类或其子类的实例。)

第一种: 线程执行体:Thread对象调用run()

具体步骤:

  1. 创建extends继承Thread类的子类。
  2. 重写Thread的run(),该run方法体囊括此线程需要完成的各种操作
  3. 创建该Thread类子类的对象(创建Thread子类的实例)
  4. 调用线程对象的start()方法,启动该线程,JVM会自动调用用户重写的那个run方法
  5. 如果想实现其他更多线程,需要创建新的线程对象。

先使用方式一:自建类继承Thread类,用户重写run方法
举例,输出1-100以内所有的偶数。

package Thread;public class EvenNumberTest {public static void main(String[] args) {//3. 创建该Thread类子类的对象(创建Thread子类的实例)PrintNumber x = new PrintNumber();//4. 调用线程对象的start()方法,启动该线程x.start();
}//5. 如果想实现其他更多线程,需要创建新的线程对象,不能再次调用已经start的线程。
}//1. 创建继承Thread类的子类class PrintNumber extends Thread{//2. 重写Thread的run(),该run方法体囊括此线程需要完成的各种操作@Overridepublic void run() {for (int i = 0; i <= 100; i++) {if (i%2==0){System.out.print(i+"\t");}}}}

注意不能让已经start的线程再次执行start(),会报错IllgealThreadStateException,正确方法就是再建一个。
输出结果:

0	2	4	6	8	10	12	14	16	18	20	22	24	26	28	30	32	34	36	38	40	42	44	46	48	50	52	54	56	58	60	62	64	66	68	70	72	74	76	78	80	82	84	86	88	90	92	94	96	98	100	
Process finished with exit code 0

举例2,一个线程输出1-100以内所有的偶数。一个线程输出1-100以内所有的奇数。

package Thread;public class Number2Thread {//3. 创建该Thread类子类的对象(创建Thread子类的实例)//4. 调用线程对象的start()方法,启动该线程,JVM会自动调用用户重写的那个run方法//5. 如果想实现其他更多线程,需要创建新的线程对象。public static void main(String[] args) {PrintEvenNum evenx = new PrintEvenNum();evenx.start();PrintOddNum oddx= new PrintOddNum();oddx.start();}
}//1. 创建继承Thread类的子类
class PrintOddNum extends Thread{//2. 重写Thread的run(),该run方法体囊括此线程需要完成的各种操作@Overridepublic void run() {for (int i = 0; i < 100; i++) {if (i%2 !=0){System.out.print("我是odd number奇数"+i+"\t");}}}
}class PrintEvenNum extends Thread{@Overridepublic void run() {for (int i = 0; i < 100; i++) {if (i%2 ==0)    {System.out.println("我是偶数even number"+i+"\t");}}}
}

下面运行结果里可以明显看出,两个thread是交互运行输出的,并不是以往常见的,一个模块整体结束再运行下一个:


我是odd number奇数1	我是odd number奇数3	我是odd number奇数5	我是odd number奇数7	我是odd number奇数9	我是odd number奇数11	我是odd number奇数13	我是odd number奇数15	我是odd number奇数17	我是odd number奇数19	我是odd number奇数21	我是odd number奇数23	我是odd number奇数25	我是odd number奇数27	我是odd number奇数29	我是odd number奇数31	我是odd number奇数33	我是odd number奇数35	我是odd number奇数37	我是odd number奇数39	我是odd number奇数41	我是odd number奇数43	我是odd number奇数45	我是odd number奇数47	我是odd number奇数49	我是odd number奇数51	我是odd number奇数53	我是odd number奇数55	我是odd number奇数57	我是odd number奇数59	我是偶数even number0	
我是偶数even number2	
我是偶数even number4	
我是偶数even number6	
我是偶数even number8	
我是偶数even number10	
我是偶数even number12	
我是偶数even number14	
我是偶数even number16	
我是偶数even number18	
我是偶数even number20	
我是偶数even number22	
我是偶数even number24	
我是odd number奇数61	我是odd number奇数63	我是odd number奇数65	我是odd number奇数67	我是odd number奇数69	我是odd number奇数71	我是odd number奇数73	我是odd number奇数75	我是odd number奇数77	我是odd number奇数79	我是odd number奇数81	我是odd number奇数83	我是odd number奇数85	我是odd number奇数87	我是odd number奇数89	我是odd number奇数91	我是odd number奇数93	我是odd number奇数95	我是odd number奇数97	我是odd number奇数99	我是偶数even number26	
我是偶数even number28	
我是偶数even number30	
我是偶数even number32	
我是偶数even number34	
我是偶数even number36	
我是偶数even number38	
我是偶数even number40	
我是偶数even number42	
我是偶数even number44	
我是偶数even number46	
我是偶数even number48	
我是偶数even number50	
我是偶数even number52	
我是偶数even number54	
我是偶数even number56	
我是偶数even number58	
我是偶数even number60	
我是偶数even number62	
我是偶数even number64	
我是偶数even number66	
我是偶数even number68	
我是偶数even number70	
我是偶数even number72	
我是偶数even number74	
我是偶数even number76	
我是偶数even number78	
我是偶数even number80	
我是偶数even number82	
我是偶数even number84	
我是偶数even number86	
我是偶数even number88	
我是偶数even number90	
我是偶数even number92	
我是偶数even number94	
我是偶数even number96	
我是偶数even number98	Process finished with exit code 0

也可以使用Thread.currentThread().getName()打印出当前thread的名字,输出时也会明显看出交替性:

    @Overridepublic void run() {for (int i = 0; i < 100; i++) {if (i%2 !=0){//System.out.print("我是odd number奇数"+i+"\t");System.out.println(Thread.currentThread().getName()+"\t"+i);}}}

结果显示,两个thread-1/0互相交替出现


Thread-1	1
Thread-1	3
Thread-1	5
Thread-1	7
Thread-1	9
Thread-1	11
Thread-1	13
Thread-1	15
Thread-1	17
Thread-1	19
Thread-1	21
Thread-1	23
Thread-1	25
Thread-1	27
Thread-1	29
Thread-1	31
Thread-1	33
Thread-1	35
Thread-1	37
Thread-1	39
Thread-1	41
Thread-1	43
Thread-1	45
Thread-1	47
Thread-1	49
Thread-1	51
Thread-1	53
Thread-1	55
Thread-1	57
Thread-1	59
Thread-1	61
Thread-1	63
Thread-1	65
Thread-1	67
Thread-1	69
Thread-1	71
Thread-1	73
Thread-1	75
Thread-0	0
Thread-0	2
Thread-0	4
Thread-0	6
Thread-0	8
Thread-0	10
Thread-0	12
Thread-0	14
Thread-0	16
Thread-0	18
Thread-0	20
Thread-0	22
Thread-0	24
Thread-0	26
Thread-0	28
Thread-0	30
Thread-0	32
Thread-0	34
Thread-0	36
Thread-0	38
Thread-0	40
Thread-0	42
Thread-0	44
Thread-0	46
Thread-0	48
Thread-0	50
Thread-0	52
Thread-0	54
Thread-0	56
Thread-0	58
Thread-1	77
Thread-0	60
Thread-1	79
Thread-0	62
Thread-1	81
Thread-0	64
Thread-1	83
Thread-0	66
Thread-1	85
Thread-0	68
Thread-1	87
Thread-0	70
Thread-1	89
Thread-0	72
Thread-1	91
Thread-0	74
Thread-1	93
Thread-1	95
Thread-1	97
Thread-1	99
Thread-0	76
Thread-0	78
Thread-0	80
Thread-0	82
Thread-0	84
Thread-0	86
Thread-0	88
Thread-0	90
Thread-0	92
Thread-0	94
Thread-0	96
Thread-0	98Process finished with exit code 0

下面对程序进行改写,试图创建Thread类的匿名子类的匿名对象,并调用其start方法
提示:可以使用new Thread(){XXX}.start();

package Thread;public class Number2Thread {
public static void main(String[] args) {//创建Thread类的匿名子类的匿名对象,并调用其start方法// new Thread(){};// new Thread(){重写run方法};// new Thread(){重写run方法}.start();new Thread(){@Overridepublic void run() {for (int i = 0; i < 100; i++) {if (i%2 !=0){//System.out.print("我是odd number奇数"+i+"\t");System.out.println(Thread.currentThread().getName()+"\t"+i);}}}}.start();new Thread(){public void run() {for (int i = 0; i < 100; i++) {if (i%2 ==0)    {//System.out.println("我是偶数even number"+i+"\t");System.out.println(Thread.currentThread().getName()+"\t"+i);}}}}.start();}
}

可以观察到,结果依旧是两个thread交替出现的

Thread-0	1
Thread-0	3
Thread-0	5
Thread-0	7
Thread-0	9
Thread-0	11
Thread-0	13
Thread-0	15
Thread-1	0
Thread-1	2
Thread-0	17
Thread-0	19
Thread-0	21
Thread-0	23
Thread-0	25
Thread-0	27
Thread-0	29
Thread-0	31
Thread-0	33
Thread-0	35
Thread-0	37
Thread-0	39
Thread-0	41
Thread-0	43
Thread-0	45
Thread-0	47
Thread-0	49
Thread-0	51
Thread-0	53
Thread-1	4
Thread-1	6
Thread-1	8
Thread-1	10
Thread-1	12
Thread-1	14
Thread-1	16
Thread-1	18
Thread-1	20
Thread-1	22
Thread-1	24
Thread-1	26
Thread-1	28
Thread-1	30
Thread-1	32
Thread-1	34
Thread-1	36
Thread-1	38
Thread-1	40
Thread-1	42
Thread-1	44
Thread-1	46
Thread-1	48
Thread-1	50
Thread-1	52
Thread-1	54
Thread-1	56
Thread-1	58
Thread-0	55
Thread-0	57
Thread-0	59
Thread-0	61
Thread-0	63
Thread-0	65
Thread-0	67
Thread-0	69
Thread-0	71
Thread-0	73
Thread-0	75
Thread-0	77
Thread-0	79
Thread-0	81
Thread-0	83
Thread-0	85
Thread-0	87
Thread-0	89
Thread-0	91
Thread-0	93
Thread-0	95
Thread-0	97
Thread-0	99
Thread-1	60
Thread-1	62
Thread-1	64
Thread-1	66
Thread-1	68
Thread-1	70
Thread-1	72
Thread-1	74
Thread-1	76
Thread-1	78
Thread-1	80
Thread-1	82
Thread-1	84
Thread-1	86
Thread-1	88
Thread-1	90
Thread-1	92
Thread-1	94
Thread-1	96
Thread-1	98Process finished with exit code 0

现在使用创建方式二:用户创建实现Runnable接口的类,再在里面重写run方法

具体步骤如下:

  1. 创建一个实现Runnable接口的类
  2. 实现接口中的run() -->将此线程要执行的操作,声明再方法体中
  3. 创建当前实现类的对象
  4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
  5. Thread类的实例调用.start()

这种思维模式可以简单解释成

- 先建一个完成Runnable接口的实现类,里面重写了run方法
- 用这个新建的实现类做一个objectA
- 将这个objectA作为参数传给Thread
- Thread调用start方法时,会使用参数objectA自己重写的run方法

IDEA快捷键ctrl+i快速生成run方法块 (自动弹出override相关method)
双击接口名称处的Runnable按键ctrl+i可以获得这个接口对应的method,选中override快速构建重写的结构。

举例:使用继承Runnable接口的方法,建立两个thread分别输出100以内能被3整除的所有数字。

package Thread;public class QuickTestRunnable {public static void main(String[] args) {PrtRunDiv3Num p1= new PrtRunDiv3Num();//只需要建立一个PrtRunDiv3Num的实例p1就行Thread y0 = new Thread(p1);Thread y1 = new Thread(p1);y1.start();y0.start();}}class PrtRunDiv3Num implements Runnable{@Overridepublic void run() {for (int i = 0; i < 100; i++) {if(i%3==0){System.out.println(Thread.currentThread().getName()+"\t"+i);}}}
}

可以看到运行结果里,两个Thread交替输出着


Thread-1	0
Thread-1	3
Thread-1	6
Thread-1	9
Thread-1	12
Thread-1	15
Thread-1	18
Thread-1	21
Thread-0	0
Thread-0	3
Thread-0	6
Thread-0	9
Thread-0	12
Thread-0	15
Thread-0	18
Thread-0	21
Thread-0	24
Thread-0	27
Thread-0	30
Thread-0	33
Thread-0	36
Thread-0	39
Thread-0	42
Thread-0	45
Thread-0	48
Thread-0	51
Thread-0	54
Thread-0	57
Thread-0	60
Thread-0	63
Thread-0	66
Thread-1	24
Thread-1	27
Thread-1	30
Thread-1	33
Thread-1	36
Thread-1	39
Thread-0	69
Thread-0	72
Thread-1	42
Thread-1	45
Thread-1	48
Thread-1	51
Thread-1	54
Thread-1	57
Thread-1	60
Thread-1	63
Thread-1	66
Thread-1	69
Thread-1	72
Thread-1	75
Thread-1	78
Thread-1	81
Thread-1	84
Thread-1	87
Thread-1	90
Thread-1	93
Thread-1	96
Thread-1	99
Thread-0	75
Thread-0	78
Thread-0	81
Thread-0	84
Thread-0	87
Thread-0	90
Thread-0	93
Thread-0	96
Thread-0	99Process finished with exit code 0

举例,使用继承Runnable接口的方法,建立两个thread分别输出1-100内所有的偶数和奇数。

package Thread;public class EvenNumberRunnableTest {//1. 创建一个实现Runnable接口的类//2. 实现接口中的run() -->将此线程要执行的操作,声明再方法体中//3. 创建当前实现类的对象//4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例//5. Thread类的实例调用.start()public static void main(String[] args) {PrintEvenNumRunnable x=new PrintEvenNumRunnable();Thread t1 = new Thread(x);t1.start();PrintOddNumRunnable y = new PrintOddNumRunnable();Thread t2 =new Thread(y);t2.start();}
}
class PrintEvenNumRunnable implements Runnable{@Overridepublic void run() {for (int i = 0; i <= 100; i++) {if(i%2==0){System.out.println(Thread.currentThread().getName()+"\t"+i);}}}
}class PrintOddNumRunnable implements Runnable{@Overridepublic void run() {for (int i = 0; i <= 100; i++) {if(i%2!=0){System.out.println(Thread.currentThread().getName()+"\t"+i);}}}
}

运行结果可以看出两个Thread交替输出:

Thread-1	1
Thread-1	3
Thread-1	5
Thread-1	7
Thread-1	9
Thread-1	11
Thread-1	13
Thread-1	15
Thread-1	17
Thread-1	19
Thread-1	21
Thread-1	23
Thread-1	25
Thread-1	27
Thread-1	29
Thread-1	31
Thread-1	33
Thread-1	35
Thread-1	37
Thread-1	39
Thread-1	41
Thread-0	0
Thread-0	2
Thread-0	4
Thread-0	6
Thread-0	8
Thread-0	10
Thread-0	12
Thread-0	14
Thread-0	16
Thread-0	18
Thread-0	20
Thread-0	22
Thread-0	24
Thread-0	26
Thread-0	28
Thread-0	30
Thread-0	32
Thread-0	34
Thread-0	36
Thread-0	38
Thread-0	40
Thread-0	42
Thread-0	44
Thread-0	46
Thread-0	48
Thread-0	50
Thread-0	52
Thread-1	43
Thread-1	45
Thread-1	47
Thread-1	49
Thread-1	51
Thread-1	53
Thread-1	55
Thread-1	57
Thread-1	59
Thread-1	61
Thread-1	63
Thread-1	65
Thread-1	67
Thread-1	69
Thread-0	54
Thread-0	56
Thread-0	58
Thread-0	60
Thread-0	62
Thread-0	64
Thread-0	66
Thread-0	68
Thread-0	70
Thread-0	72
Thread-0	74
Thread-0	76
Thread-0	78
Thread-0	80
Thread-0	82
Thread-0	84
Thread-0	86
Thread-0	88
Thread-0	90
Thread-0	92
Thread-0	94
Thread-0	96
Thread-0	98
Thread-1	71
Thread-1	73
Thread-1	75
Thread-1	77
Thread-1	79
Thread-1	81
Thread-1	83
Thread-1	85
Thread-1	87
Thread-1	89
Thread-0	100
Thread-1	91
Thread-1	93
Thread-1	95
Thread-1	97
Thread-1	99Process finished with exit code 0

用匿名实现类对上述程序进行改写,采用Runnable接口匿名实现类的匿名对象简化程序

提示,可使用格式 new Thread(new Runnable() {public void run() {XXX} }).start();调用start结构

package Thread;public class EvenNumberRunnableTest {public static void main(String[] args) {new Thread(new Runnable(){public void run() {for (int i = 0; i <= 100; i++) {if(i%2==0){System.out.println(Thread.currentThread().getName()+"\t"+i);}}}}).start();//PrintOddNumRunnable y = new PrintOddNumRunnable();new Thread(new Runnable(){public void run() {for (int i = 0; i <= 100; i++) {if(i%2==0){System.out.println(Thread.currentThread().getName()+"bobo"+"\t"+i);}}}}).start();}
}

输出显示确实是交替输出的


Thread-0	0
Thread-0	2
Thread-0	4
Thread-0	6
Thread-0	8
Thread-0	10
Thread-0	12
Thread-0	14
Thread-0	16
Thread-0	18
Thread-0	20
Thread-0	22
Thread-0	24
Thread-0	26
Thread-0	28
Thread-0	30
Thread-0	32
Thread-0	34
Thread-0	36
Thread-0	38
Thread-1bobo	0
Thread-0	40
Thread-0	42
Thread-0	44
Thread-0	46
Thread-0	48
Thread-0	50
Thread-0	52
Thread-0	54
Thread-0	56
Thread-0	58
Thread-0	60
Thread-0	62
Thread-0	64
Thread-0	66
Thread-0	68
Thread-0	70
Thread-0	72
Thread-0	74
Thread-0	76
Thread-0	78
Thread-0	80
Thread-0	82
Thread-0	84
Thread-0	86
Thread-0	88
Thread-0	90
Thread-0	92
Thread-0	94
Thread-0	96
Thread-0	98
Thread-0	100
Thread-1bobo	2
Thread-1bobo	4
Thread-1bobo	6
Thread-1bobo	8
Thread-1bobo	10
Thread-1bobo	12
Thread-1bobo	14
Thread-1bobo	16
Thread-1bobo	18
Thread-1bobo	20
Thread-1bobo	22
Thread-1bobo	24
Thread-1bobo	26
Thread-1bobo	28
Thread-1bobo	30
Thread-1bobo	32
Thread-1bobo	34
Thread-1bobo	36
Thread-1bobo	38
Thread-1bobo	40
Thread-1bobo	42
Thread-1bobo	44
Thread-1bobo	46
Thread-1bobo	48
Thread-1bobo	50
Thread-1bobo	52
Thread-1bobo	54
Thread-1bobo	56
Thread-1bobo	58
Thread-1bobo	60
Thread-1bobo	62
Thread-1bobo	64
Thread-1bobo	66
Thread-1bobo	68
Thread-1bobo	70
Thread-1bobo	72
Thread-1bobo	74
Thread-1bobo	76
Thread-1bobo	78
Thread-1bobo	80
Thread-1bobo	82
Thread-1bobo	84
Thread-1bobo	86
Thread-1bobo	88
Thread-1bobo	90
Thread-1bobo	92
Thread-1bobo	94
Thread-1bobo	96
Thread-1bobo	98
Thread-1bobo	100Process finished with exit code 0

两种线程创建方法,
共同点:都需要重写Run()方法,但也不尽相同。一个是继承Thread方法里面的 Run(); 一个是实现 Runnable接口的Run()
创建的线程对象,都是Thread类以及其子类的实例。
启动Thread调用的都是Thread里面的start

不同点:一个是继承于Thread类,一个是实现Runnable接口
==更建议使用Runnable接口的方式。==原因:1.避免类的单继承局限性 2.当遇到多个线程共享数据时候更好处理 3.实现代码和数据分离

联系:打开Thread类,就会发现最上面写的是
public class Thread implements Runnable {...
Thread类自己也是继承了Runnable接口的实现类。

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

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

相关文章

CSS实现元素边框渐变动画

前言&#xff1a; 边框流动动画是一种非常常见的效果&#xff0c;能够让网页看起来更加生动有趣。通过使用 CSS3&#xff0c;我们可以轻松地实现这种动画效果。本文将介绍如何使用 CSS3 实现边框流动效果&#xff0c;下面一起来看看吧。 示例图&#xff1a;边框是动画持续变化的…

前端简历:大学还没毕业,就写2年工作经验,上的啥大学呢?

我看过很多前端简历&#xff0c;不知道是不是被所谓简历专家和面试专家给拐带的&#xff0c;还没毕业就敢写2年工作经验&#xff0c;如果属实&#xff0c;大学上了个啥&#xff1f; 简历每天都能收到几十上百封&#xff0c;对于初级人才招聘&#xff0c;基本上看以下几点。 1、…

CIM搭建实现发送消息的效果

目录 背景过程1、下载代码2、进行配置3、直接启动项目4、打开管理界面5、启动web客户端实例项目6、发送消息 项目使用总结 背景 公司项目有许多需要发送即时消息的场景&#xff0c;之前一直采用的是传统的websocket连接&#xff0c;它会存在掉线严重&#xff0c;不可重连&…

深入理解数据结构(3):栈和队列详解

文章主题&#xff1a;顺序表和链表详解&#x1f331;所属专栏&#xff1a;深入理解数据结构&#x1f4d8;作者简介&#xff1a;更新有关深入理解数据结构知识的博主一枚&#xff0c;记录分享自己对数据结构的深入解读。&#x1f604;个人主页&#xff1a;[₽]的个人主页&#x…

瑞吉外卖实战学习--7、员工信息分页查询

员工信息分页查询 前言1、配置公共分页组件2、创建接口并查看接收的参数3、使用分页构造器并添加查询条件和排序条件4、测试结果 前言 1、配置公共分页组件 package com.example.ruiji_demo.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;…

sharemore少数派提示词或许需要工程,但提问一定需要智慧

Matrix 首页推荐 Matrix 是少数派的写作社区&#xff0c;我们主张分享真实的产品体验&#xff0c;有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章&#xff0c;展示来自用户的最真实的体验和观点。 文章代表作者个人观点&#xff0c;少数派仅对标题和排版略作…

代码随想录算法训练营第二十五天| 216.组合总和III,17.电话号码的字母组合

题目与题解 216.组合总和III 题目链接&#xff1a;216.组合总和III 代码随想录题解&#xff1a;216.组合总和III 视频讲解&#xff1a;和组合问题有啥区别&#xff1f;回溯算法如何剪枝&#xff1f;| LeetCode&#xff1a;216.组合总和III_哔哩哔哩_bilibili 解题思路&#xf…

数据结构和算法:图

图 图&#xff08;graph&#xff09;是一种非线性数据结构&#xff0c;由顶点&#xff08;vertex&#xff09;和边&#xff08;edge&#xff09;组成。可以将图 &#x1d43a; 抽象地表示为一组顶点 &#x1d449; 和一组边 &#x1d438; 的集合。 如果将顶点看作节点&#…

9.2-源码分析:Dubbo Remoting 层 Buffer 缓冲区

Buffer 是一种字节容器&#xff0c;在 Netty 等 NIO 框架中都有类似的设计&#xff0c;例如&#xff0c;Java NIO 中的ByteBuffer、Netty4 中的 ByteBuf。Dubbo 抽象出了 ChannelBuffer 接口对底层 NIO 框架中的 Buffer 设计进行统一&#xff0c;其子类如下图所示&#xff1a; …

Oracle数据库——子查询五

14.1子查询语法 子查询 (内查询) 在主查询之前一次执行完成。子查询的结果被主查询(外查询)使用 。范例一:谁的工资比 Abel 高? 第一:查询Abel的工资是多少。第二:比较大于这个工资的人数。 注意事项: 子查询要包含在括号内。将子查询放在比较条件的右侧。</

文件名目录名或卷标语法不正确:数据恢复策略与预防措施

一、文件名目录名或卷标语法不正确的现象 在日常使用电脑或移动设备时&#xff0c;我们经常会遇到“文件名目录名或卷标语法不正确”的错误提示。这种错误通常发生在尝试访问、修改或删除文件、目录或卷标时&#xff0c;系统会提示无法完成操作&#xff0c;因为文件名、目录名…

C++格式化输入和输出

格式化输入与输出 除了条件状态外&#xff0c;每个iostream对象还维护一个格式状态来控制IO如何格式化的细节。 格式状态控制格式化的某些方面&#xff0c;如整型值是几进制、浮点值的精度、一个输出元素的宽度等。 标准库定义了一组操纵符来修改流的格式状态。 一个操纵符…

电商系列之商详

> 插&#xff1a;AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

java解数独(力扣Leetcode37)

数独问题 力扣原题链接 问题描述 数独的解法需遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 数独部分空格内已填入了数字&#xff0c;空白格用.表示。 示例 示例&…

微服务监控:确保分布式系统的可观察性与稳定性

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 目录 一、前言二、微服务监控的重要性三、关键监控指标四、常用监控工具五、最佳实践六、结论 一、前言 在当前的软件开发领域&a…

const在指针中的作用以及*p在各种写法中分别代表什么含义

const在指针中起固定的作用&#xff0c;在不同的写法中其效果也有所区别&#xff0c;具体如下&#xff1a; 1、int* const p固定的是指针p指向的地址。 2、int const *p固定的是指针p指向地址中储存的内容。 例&#xff1a; 以上操作在编译器中执行不了&#xff0c;会报错。…

flutter生成二维码并截图保存到图库

引入库&#xff1a;flutter_screenutil、image_gallery_saver、qr_flutter弹窗布局 import dart:async; import dart:typed_data; import package/generated/l10n.dart; import package:jade/configs/PathConfig.dart; import package:jade/utils/ImageWaterMarkUtil.dart; im…

瑞吉外卖实战学习--8、人员禁用和启用

前言 1、通过前端页面查看接口 会发现请求方式是put 请求接口是employee 2、检查页面传值 根据浏览器的请求可以看到传值为id和status 2、写put请求&#xff0c;添加修改时间和修改人的id然后传回给后台 /*** 启用和禁用员工账号* param request* param employee* return…

【Consul】Linux安装Consul保姆级教程

【Consul】Linux安装Consul保姆级教程 大家好 我是寸铁&#x1f44a; 总结了一篇【Consul】Linux安装Consul保姆级教程✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言 今天要把编写的go程序放到linux上进行测试Consul服务注册与发现&#xff0c;那怎么样才能实现这一过程&am…

25Ramdisk 启动模式简介

Ramdisk 启动模式简介 ramdisk是一种虚拟磁盘技术,我们的PE系统几乎都是使用ramdisk方式从计算机启动的.那么,ramdisk有哪些特点呢? Ramdisk 将内存虚拟为一个磁盘 Ramdisk技术会将你的一部分内存虚拟成一块磁盘分区.使用U盘启动pe系统时,打开pe系统里的文件资源管理器,你会看…