多线程原理详解01(程序、进程、线程介绍,线程创建的三种方式(Thread、Runnable、Callable)、三种方式各自实现多线程的具体操作、代码解析)

目录

  • 多线程原理详解
    • 01_线程简介
      • 多任务
      • 多线程
      • 程序、进程、线程
      • Process(进程)与 Thread (线程)
      • 总结:
    • 02_线程创建三种方式:
      • 1、继承 Thread 类
        • 1-1:通过继承Thread类实现多线程
          • 演示代码
        • 1-2:演示多线程同步下载图片:
          • 演示代码
      • 2、实现 Runnable 接口 (推荐)
        • 2-1:通过实现Runnable接口来实现多线程
          • 具体代码
        • 2-2:通过实现Runnable接口来实现多线程同步下载图片
          • 具体代码
        • 2-3:演示多个线程同时操作同一个对象出现的并发问题
          • 演示买火车票的例子
            • 具体代码
          • 通过 synchronized 关键字同步代码块解决并发问题
            • 具体代码
        • 2-4:演示龟兔赛跑案例
          • 用多线程的方式模拟龟兔赛跑代码分析
          • 具体代码
      • 3、实现 Callable 接口
        • 演示多线程同时下载图片
        • 具体代码
      • 4、总结:三种创建方式的区别:

多线程原理详解


01_线程简介

任务、进程、线程、多线程


多任务

就是在一个时间内做很多事情,比如边吃饭变玩手机,但是本质上,在那一秒内,其实只是在玩手机,或者在一秒内只是在吃饭。
看起来像是多个任务都在做,其实本质上我们的大脑在同一时间依旧只做了一件事情而已

在这里插入图片描述


多线程

比如原本一条道路看成一个线程,多辆车都在一个道路上形式,容易出问题。
但是如果给道路划分路线,相当于弄多条线程,让多辆车在各自的线程行驶,出问题的概率就变小。
在这里插入图片描述

平常项目中的普通的方法调用,基本是一条线程走到底,即使调用方法,也是在方法执行完后继续往下走,只用到主线程而已。

多线程就是多条线程各自执行,效率更高。

就像一个大超市,只有一个收银员(单线程)和多个收银员(多线程)的区别。

在这里插入图片描述


程序、进程、线程

在操作系统中运行的程序就是进程,比如微信、QQ、腾讯视频、游戏这些就是程序,也就是进程

一个进程(腾讯视频)可以有多个线程(视频声音、图像、弹幕等)

在这里插入图片描述


Process(进程)与 Thread (线程)

程序(静态的)–>程序跑起来变成进程(动态的)–>进程里面包含多个线程,真正执行功能的就是这些线程

在这里插入图片描述


总结:

在这里插入图片描述

注意:

单核 CPU 上所谓的"多线程"那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行罢了。

多核 CPU 上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核 CPU 的优势来,达到充分利用 CPU 的目的



02_线程创建三种方式:

三种创建方式主要是:继承 Thread 类、实现 Runnable 接口,还有一个是 实现 Callable 接口

最好的是实现 Runnable 接口,因为实现接口的方式比继承类的方式更灵活,也能减少程序之间的耦合度。

这三种方式都能开启多个线程来执行业务逻辑。


1、继承 Thread 类

步骤:

1、自定义一个类,继承 Thread 类;
2、重写 run() 方法,编写线程执行体;
3、创建线程对象,调用 start() 方法启动线程;


解释:

自定义一个类去继承Thread 类,作为一个线程类对象,然后就可以重写Thread类的 run() 方法;
接着在main主线程里面,可以通过线程对象去调用 start() 方法,该方法的作用是让 java 虚拟机去启动一个新的线程去执行 run() 方法里面的代码。
然后主线程继续执行自己的业务代码。

这样主线程和新的线程就都同时执行,这个就是多线程操作。


1-1:通过继承Thread类实现多线程

当我们调用 start() 方法后,start() 方法会通知 Java 虚拟机启动一个新线程(也就是子线程),并在新线程中调用该线程对象(t1)的 run() 方法。

而主线程调用start() 方法后,也会继续执行下面的代码。

这个时候,主线程和新线程就会并发执行,这样就演示出了多线程并发执行的特性。

在这里插入图片描述


演示代码

//创建线程方式一:继承 Thread 类, 重写 run() 方法,调用 start() 方法开启线程
//注意:线程开启不一定立即执行,由 CPU 调度执行
public class TestThread01 extends Thread
{//重写 run() 方法@Overridepublic void run(){//run 方法线程体for (int i = 0; i < 20; i++){System.err.println("run方法线程:bbbbbb--->" + i);}}//main 主线程public static void main(String[] args){//创建一个线程对象TestThread01 t1 = new TestThread01();//直接调用run方法,只是普通的调用,跟多线程没有关系//t1.run();//调用start()方法开启线程,主线程和run()方法的线程就会同时进行t1.start();for (int i = 0; i < 20; i++){System.err.println("main主线程:aaaaaaaaaa--->" + i);}}}

1-2:演示多线程同步下载图片:

先下载一个 Apache 的 Commons IO 的 jar 包,是一个文件下载的工具类库

在这里插入图片描述

下载之后解压,把这个 jar 包拷贝到项目里面去

在这里插入图片描述

点击右键,点击【Add library】添加进去即可。
有了这个工具类库,才可以使用比如 FileUtils 这样的工具类

在这里插入图片描述


代码实现:

代码中,可以看出如果是单线程下载这3张图片的话,下载顺序应该是1、2、3
可从结果看,下载顺序是3、2、1,说明是多线程在同步下载图片,哪条线程快就哪条先下载完。

在这里插入图片描述


如图,图片成功下载下来了,这图片是我其他 博客文章里面的图片

在这里插入图片描述


演示代码
package cn.ljh.threaddemo.demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;// 实现多线程同步下载图片
public class TestThread02 extends Thread
{private String url; //网络图片地址private String name;//保存的文件名//构造器public TestThread02(String url ,String name){this.url = url;this.name = name;}//重写run方法@Overridepublic void run(){//run方法里面调用了文件下载的downloader方法WebDownloader webDownloader = new WebDownloader();webDownloader.downloader(url,name);System.err.println("下载了文件名为:"+ name);}//主线程public static void main(String[] args){//创建三个线程对象TestThread02 t1 = new TestThread02("https://img-blog.csdnimg.cn/direct/0aded64215424e0488d3da76357750b6.png","1.jpg");TestThread02 t2 = new TestThread02("https://img-blog.csdnimg.cn/direct/0aded64215424e0488d3da76357750b6.png","2.jpg");TestThread02 t3 = new TestThread02("https://img-blog.csdnimg.cn/direct/0aded64215424e0488d3da76357750b6.png","3.jpg");//启动3条线程t1.start();t2.start();t3.start();}
}//图片下载器
class WebDownloader{//下载方法public void downloader(String url,String  name){try{//把网络图片地址url变成一个文件,参数1:网络图片地址 ;参数2:下载后保存的文件名FileUtils.copyURLToFile(new URL(url),new File(name));} catch (IOException e){e.printStackTrace();System.err.println("IO异常,downloader 方法出现问题");}}}


2、实现 Runnable 接口 (推荐)

步骤:

1、自定义一个类,实现 Runnable 接口;
2、实现 run() 方法,编写线程执行体;
3、创建线程对象,调用 start() 方法启动线程;


2-1:通过实现Runnable接口来实现多线程

这个和上面继承 Thread 类的操作差别不大。

如图:这个实现了Runnable接口的自定义线程类TestThread03,作为参数传进到 Thread 这个线程对象里面,然后通过 Thread 这个线程对象调用 start() 方法启动新线程。

解释下这个自定义线程类TestThread03,为什么说它是一个代理对象。

详细解释:

代码中:
将 t 视为一个代理对象的原因是它充当了线程对象(thread)和具体任务逻辑之间的中介。

具体来说,t 自定义线程类对象 实现了 Runnable 接口,并在其 run() 方法中定义了线程要执行的任务逻辑。

当我们通过 Thread 类创建一个 thread 对象时,需要将一个实现了 Runnable接口的对象(t)作为参数传入,那么这个对象(t)就是线程对象(thread)的代理,它 (t) 负责管理线程的生命周期和执行任务的逻辑。

在调用 thread.start() 方法后,线程对象(thread)会自动调用代理对象(t)的 run() 方法,从而执行具体的任务逻辑。

t 作为一个代理对象,充当了线程对象(thread)和具体任务逻辑之间的桥梁,使得线程的管理和任务的执行能够分开进行,提高了代码的灵活性和可维护性。

简单来说:

实现了Runnable接口的t对象,它实现了run()方法,作用是在run()方法里面写具体的业务逻辑代码。

而创建一个 Thread 对象,作用是用来调用 start() 方法从而启动新线程。

而启动的新线程要执行的业务逻辑代码在t对象的run()方法里面,所以就把 t 作为代理对象传给 thread 对象。

这样就是通过代理的方式实现了线程的启动(thread.start())和任务(任务在run()方法里面)的执行。

在这里插入图片描述

和上面的继承 Thread 类差不多。

再简洁的说法:

继承 Thread 类的自定义线程类对象,是自身调用 start 方法启动新线程。

实现Runnable 接口的自定义线程类对象,是作为创建Thread线程对象的参数,由Thread线程对象来调用start方法启动新线程


具体代码
package cn.ljh.threaddemo.demo01;//创建线程方式2:实现 Runnable 接口,重写 run 方法,执行线程需要丢入 runnable 接口实现类,调用 start 方法public class TestThread03 implements Runnable
{//实现 run() 方法@Overridepublic void run(){//run 方法线程体for (int i = 0; i < 20; i++){System.err.println("run方法线程:bbbbbb--->" + i);}}//main 主线程public static void main(String[] args){//创建 Runnable 接口的实现类对象TestThread03 t = new TestThread03();//创建线程对象,通过线程对象thread来开启我们的线程---代理对象tThread thread = new Thread(t);thread.start();for (int i = 0; i < 20; i++){System.err.println("main主线程:aaaaaaaaaa--->" + i);}}
}

2-2:通过实现Runnable接口来实现多线程同步下载图片

小小区别:

在这里插入图片描述


具体代码
// 实现多线程同步下载图片
public class TestThread04 implements Runnable
{private String url; //网络图片地址private String name;//保存的文件名//构造器public TestThread04(String url ,String name){this.url = url;this.name = name;}//重写run方法@Overridepublic void run(){//run方法里面调用了文件下载的downloader方法WebDownloader04 webDownloader = new WebDownloader04();webDownloader.downloader(url,name);System.err.println("下载了文件名为:"+ name);}//主线程public static void main(String[] args){//创建三个线程对象TestThread04 t1 = new TestThread04("https://img-blog.csdnimg.cn/direct/0aded64215424e0488d3da76357750b6.png","1.jpg");TestThread04 t2 = new TestThread04("https://img-blog.csdnimg.cn/direct/0aded64215424e0488d3da76357750b6.png","2.jpg");TestThread04 t3 = new TestThread04("https://img-blog.csdnimg.cn/direct/0aded64215424e0488d3da76357750b6.png","3.jpg");//通过线程对象启动3条线程Thread thread = new Thread(t1);thread.start();new Thread(t2).start();new Thread(t3).start();}
}//图片下载器
class WebDownloader04{//下载方法public void downloader(String url,String  name){try{//把网络图片地址url变成一个文件,参数1:网络图片地址 ;参数2:下载后保存的文件名FileUtils.copyURLToFile(new URL(url),new File(name));} catch (IOException e){e.printStackTrace();System.err.println("IO异常,downloader 方法出现问题");}}
}


2-3:演示多个线程同时操作同一个对象出现的并发问题

演示买火车票的例子

演示多个线程同时操作同一个对象—以买火车票为例子

多个线程操作同一个资源的情况下,线程不安全,数据紊乱,
这个就是多线程情况下会出现的并发问题。

在这里插入图片描述


具体代码
//演示多个线程同时操作同一个对象---以买火车票为例子
//出现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
public class TestThread05 implements Runnable
{//票数private int ticketNums = 10;@Overridepublic void run(){while (true){if (ticketNums<=0){//终止当前所在循环break;}//模拟延迟try{Thread.sleep(500);} catch (InterruptedException e){e.printStackTrace();}System.err.println(Thread.currentThread().getName()+"--->买到了第【 "+ticketNums-- + " 】张票");}}public static void main(String[] args){TestThread05 t = new TestThread05();//启动新线程  参数1:t 就是代理对象   参数2:name 就是当前线程名字new Thread(t,"小黄").start();new Thread(t,"小白").start();new Thread(t,"小绿").start();}
}

通过 synchronized 关键字同步代码块解决并发问题

简单解决下上面买车票的并发问题:

使用 synchronized 保证同一时间只有一个线程能来操作这个代码块。

在这里插入图片描述


具体代码
package cn.ljh.threaddemo.demo01;//演示多个线程同时操作同一个对象---以买火车票为例子
//出现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
public class TestThread05 implements Runnable
{//票数private int ticketNums = 10;@Overridepublic void run(){while (true){synchronized (this){if (ticketNums <= 0){//终止当前所在循环break;}System.err.println(Thread.currentThread().getName()+ "--->买到了第【 " + ticketNums-- + " 】张票");}//模拟延迟try{Thread.sleep(500);} catch (InterruptedException e){e.printStackTrace();}}}public static void main(String[] args){TestThread05 t = new TestThread05();//启动新线程  参数1:t 就是代理对象   参数2:name 就是当前线程名字Thread t1 = new Thread(t, "小黄");Thread t2 = new Thread(t, "小白");Thread t3 = new Thread(t, "小绿");t1.start();t2.start();t3.start();}
}

2-4:演示龟兔赛跑案例

自定义一个线程类,实现 Runnable 接口,然后启动两个线程(一个兔子线程和一个乌龟线程),用for循环,看哪个线程先执行到100米。

在这里插入图片描述


用多线程的方式模拟龟兔赛跑代码分析

在这里插入图片描述


具体代码

// 模拟龟兔赛跑案例
public class Race implements Runnable
{//胜利者private static String winner;//实现 run() 方法@Overridepublic void run(){for (int i = 0; i <= 100; i++){//模拟兔子休息--当前线程是"兔子" 并且 每跑10步,就休息一会if (Thread.currentThread().getName().equals("兔子") && i%10==0){try{Thread.sleep(5);} catch (InterruptedException e){e.printStackTrace();}}//判断比赛是否结束boolean flag = gameOver(i);//如果flag为true,表示比赛结束,直接终止当前所在循环if (flag){break;}System.err.println(Thread.currentThread().getName()+ " ---> 跑了【 " + i + " 】步");}}//主线程public static void main(String[] args){Race race = new Race();//启动名为兔子的新线程new Thread(race, "兔子").start();//启动名为乌龟的新线程new Thread(race, "乌龟").start();}//判断是否完成比赛的方法public boolean gameOver(int steps){//判断是否有胜利者if (winner != null){//已经存在胜利者了,返回truereturn true;} else if (steps >= 100){winner = Thread.currentThread().getName();System.err.println("胜利者是:【 " + winner + " 】");return true;}return false;}
}


3、实现 Callable 接口

步骤:

在这里插入图片描述


演示多线程同时下载图片

演示的依然是这个多线程同时下载图片的功能,不过这里是实现 Callable 接口。

这里的多线程操作,是通过创建一个线程池,然后把实现了 Callable 接口的自定义线程类对象(t1、t2、t3)作为任务参数提交给线程池去执行,并且可以获取线程执行后的结果,最后关闭线程池。

t1、t2、t3各自代表一个任务,它们实现了Callable接口,并且在call()方法中定义了具体的任务逻辑。
提交t1、t2、t3任务给线程池后,线程池会负责安排线程来执行t1、t2、t3中定义的任务逻辑。

在这里插入图片描述

通过源码可以看出 ,Callable 接口里面只有一个 call() 方法需要重写
在这里插入图片描述


具体代码
import org.apache.commons.io.FileUtils;import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;//线程创建方式三:实现 Callable 接口
/*** Callable 的好处* 1、可以定义返回值* 2、可以抛出异常*/// 实现多线程同步下载图片
public class TestCallable implements Callable<Boolean>
{private String url; //网络图片地址private String name;//保存的文件名//构造器public TestCallable(String url, String name){this.url = url;this.name = name;}//实现 Call 方法@Overridepublic Boolean call() throws Exception{//run方法里面调用了文件下载的downloader方法WebDownloader webDownloader = new WebDownloader();webDownloader.downloader(url, name);System.err.println("下载了文件名为:" + name);//返回true表示任务执行成功return true;}//主线程public static void main(String[] args) throws Exception{//创建三个线程对象TestCallable t1 = new TestCallable("https://img-blog.csdnimg.cn/direct/beb94daf07094fd5979693243c8ac60b.png","1.jpg");TestCallable t2 = new TestCallable("https://img-blog.csdnimg.cn/direct/beb94daf07094fd5979693243c8ac60b.png","2.jpg");TestCallable t3 = new TestCallable("https://img-blog.csdnimg.cn/direct/beb94daf07094fd5979693243c8ac60b.png","3.jpg");//ExecutorService是Java中用于管理线程池的接口,通过ExecutorService,可以创建一个线程池,并使用该线程池执行任务// 1、创建执行服务:创建了一个固定大小为3的线程池,这意味着该线程池最多同时运行3个线程    fixed:固定的ExecutorService ser = Executors.newFixedThreadPool(3);// 2、提交执行:使用ExecutorService的submit()方法提交了三个任务(t1、t2、t3)给线程池执行,并且通过Future对象(r1、r2、r3)接收返回结果Future<Boolean> r1 = ser.submit(t1);Future<Boolean> r2 = ser.submit(t2);Future<Boolean> r3 = ser.submit(t3);// 3、获取返回值结果Boolean result1 = r1.get();Boolean result2 = r2.get();Boolean result3 = r3.get();System.err.println(result1);System.err.println(result2);System.err.println(result3);// 4、关闭服务,也就是关闭线程池ser.shutdown();}//图片下载器class WebDownloader{//下载方法public void downloader(String url, String name){try{//把网络图片地址url变成一个文件,参数1:网络图片地址 ;参数2:下载后保存的文件名FileUtils.copyURLToFile(new URL(url), new File(name));} catch (IOException e){e.printStackTrace();System.err.println("IO异常,downloader 方法出现问题");}}}
}

4、总结:三种创建方式的区别:

Thread、Runnable、Callable,都能用来开启多个线程来执行业务逻辑。

继承Thread 类 和 实现 Runnable接口的对比:

OOP 指的是面向对象编程(Object-Oriented Programming)
在这里插入图片描述


继承 Thread 类:(重写run()方法)
自定义线程子类A,继承 Thread 类,然后重写 run() 方法,把具体的业务逻辑写在run方法里面。
通过子类自身去调用 start() 方法,让 JVM 去开启一条新的线程去执行 run() 方法。

这样就可以启动多条线程。


实现 Runnable 接口:(实现 run() 方法)
自定义线程类B,实现 Runnable 接口,它启动多个线程,是通过 创建多个Thread 线程对象,然后把线程类B作为参数传给 Thread 线程对象,由Thread线程对象来调用 start 方法的


实现 Callable 接口:(实现 call() 方法)

自定义线程类C,实现 Callable 接口,它启动多个线程,是通过创建一个线程池,然后把线程类对象C作为任务参数提交到线程池,由线程池负责提供新线程来执行线程类对象C中定义的任务逻辑
线程类对象C中定义的任务逻辑,就是指重写 call() 方法里面的业务逻辑。


在这里插入图片描述



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

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

相关文章

如果用大模型考公,kimi、通义千问谁能考高分?

都说大模型要超越人类了&#xff0c;今天就试试让kimi和通义千问做公务员考试题目&#xff0c;谁能考高分&#xff1f; 测评结果再次让人震惊&#xff01; 问题提干&#xff1a;大小两种规格的盒装鸡蛋&#xff0c;大盒装23个&#xff0c;小盒装16个&#xff0c;采购员小王买了…

LangChain入门:14.LLMChain:最简单的链的使用

摘要 本文将介绍LangChain库中LLMChain工具的使用方法。LLMChain将提示模板、语言模型&#xff08;LLM&#xff09;和输出解析器整合在一起&#xff0c;形成一个连贯的处理链&#xff0c;简化了与语言模型的交互过程。我们将探讨LLMChain的技术特点、应用场景以及它解决的问题…

Day84:服务攻防-端口协议桌面应用QQWPS等RCEhydra口令猜解未授权检测

目录 端口协议-口令爆破&未授权 弱口令爆破 FTP&#xff1a;文件传输协议 RDP&#xff1a;Windows远程桌面协议 SSH&#xff1a;Linux安全外壳协议 未授权案例(rsync) 桌面应用-QQ&WPS&Clash QQ RCE 漏洞复现 WPS RCE 漏洞复现 Clas* RCE 漏洞复现 知识点…

Android图形显示架构概览

图形显示系统作为Android系统核心的子系统&#xff0c;掌握它对于理解Android系统很有帮助&#xff0c;下面从整体上简单介绍图形显示系统的架构&#xff0c;如下图所示。 这个框架只包含了用户空间的图形组件&#xff0c;不涉及底层的显示驱动。框架主要包括以下4个图形组件。…

线程间的通信

文章目录 线程间的通讯技术就是通过等待和唤醒机制&#xff0c;来实现多个线程协同操作完成某一项任务&#xff0c;例如经典的生产者和消费者案例。等待唤醒机制其实就是让线程进入等待状态或者让线程从等待状态中唤醒&#xff0c;需要用到两种方法&#xff0c;如下&#xff1a…

如何使用群晖Synology Drive结合cpolar内网穿透实现同步Obsidian笔记文件

文章目录 一、简介软件特色演示&#xff1a; 二、使用免费群晖虚拟机搭建群晖Synology Drive服务&#xff0c;实现局域网同步1 安装并设置Synology Drive套件2 局域网内同步文件测试 三、内网穿透群晖Synology Drive&#xff0c;实现异地多端同步Windows 安装 Cpolar步骤&#…

【webrtc】源码下载与编译

目录 下载 下依赖 参考文章 &#xff1a; 下载 (1) windows ,centos上都会报错 &#xff08;2&#xff09; ubuntu A : 在git上设置代理 B fetch通过 ubuntu的界面 proxy设置了代理 这将会拉取webRTC源码&#xff0c;且额外加了android相关的依赖&#xff0c;例如And…

go语言学习--3.常用语句

目录 1.条件语句 1.1 if语句 1.2 if-else语句 1.3 switch语句 1.4 select语句 2.循环语句 2.1循环处理语句 2.2循环控制语句 3.go语言关键字 1.条件语句 和c语言类似&#xff0c;相关的条件语句如下表所示&#xff1a; 1.1 if语句 if 布尔表达式 {/* 在布尔表达式为 t…

关于JVM-三色标记算法剖析

相关系列 深入理解JVM垃圾收集器-CSDN博客 深入理解JVM垃圾收集算法-CSDN博客 深入理解jvm执行引擎-CSDN博客 jvm优化原则-CSDN博客 jvm流程图-CSDN博客 三色标记产生的原因&#xff1f; 在并发标记的过程中&#xff0c;因为标记期间应用线程还在继续跑&#xff0c;对象间的引…

postgresql发布和订阅

一、发布订阅介绍 发布和订阅使用了pg的逻辑复制的功能&#xff0c;通过发布端创建publication与表绑定&#xff0c;订阅端创建subscription同时会在发布端创建逻辑复制槽实现逻辑复制功能 逻辑复制基于 发布&#xff08;Publication&#xff09; 与 订阅&#xff08;Subscri…

使用aspose相关包将excel转成pdf 并导出

SpringBoot 项目 基于aspose相关jar包 将excel 转换成pdf 导出 1、依赖的jar包 &#xff0c; jar获取链接 aspose相关三方jar &#xff0c;下载解压后,在项目路径下建一个libs包&#xff0c;然后将下图两个jar 拷贝至刚新建的libs目录中 2、pom.xml中加入maven引入 <depend…

服务器 安装1Panel服务器运维管理面板

服务器 安装1Panel服务器运维管理面板 SSH链接服务器安装1Panel 出现此提示时输入目标路径&#xff0c;须以“/”开头&#xff0c;默认&#xff1a;/opt&#xff0c;本例&#xff1a;/www。 出现此提示时输入目标端口&#xff0c;须未被使用的端口&#xff0c;默认&#xff1…

电力变压器数据集介绍和预处理

1 电力变压器数据集介绍 1.1 数据背景 在这个Github仓库中&#xff0c;作者提供了几个可以用于长序列时间序列问题的数据集。所有数据集都经过了预处理&#xff0c;并存储为.csv文件。数据集的范围从2016/07到2018/07。 ETT-small: 含有2个电力变压器&#xff08;来自2个站点…

pringboot2集成swagger2出现guava的FluentIterable方法不存在

错误信息 Description: An attempt was made to call a method that does not exist. The attempt was made from the following location: springfox.documentation.spring.web.scanners.ApiListingScanner.scan(ApiListingScanner.java:117) The following method did not ex…

Qt 中的项目文件解析和命名规范

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、Qt项目文件解析 1、.pro 文件解析 2、widget.h 文件解析 3、main.cpp 文件解析 4、widget.cpp…

uniapp引入微信小程序版本VantUI,使用VantUI的自定义tabbar,并解决自定义tabbar出现闪烁的情况

视频教程地址&#xff1a;https://www.bilibili.com/video/BV13m41167iG 1.uniapp引入微信小程序版本VantUI 去vant官网下载源码&#xff0c;源码放在github&#xff0c;自行去下载下来 https://vant-contrib.gitee.io/vant-weapp/#/home 在pages.json的globalStyle里面注册组…

k8s的ca以及相关证书签发流程

k8s的ca以及相关证书签发流程 1. kube-apiserver相关证书说明2. 生成CA凭证1.1. 生成CA私钥1.2. 生成CA证书 2. 生成kube-apiserver凭证2.1. 生成kube-apiserver私钥2.2. 生成kube-apiserver证书请求2.3. 生成kube-apiserver证书 3. 疑问和思考4. 参考文档 对于网站类的应用&am…

中颖51芯片学习3. 定时器

中颖51芯片学习3. 定时器 一、SH79F9476定时器简介1. 简介2. 定时器运行模式 二、定时器21. 说明&#xff08;1&#xff09;时钟&#xff08;2&#xff09;工作模式 2. 寄存器&#xff08;1&#xff09;控制寄存器 T2CON&#xff08;2&#xff09;定时器2模式控制寄存器 T2MOD …

thinkphp6使用阿里云SDK发送短信

使用composer安装sdk "alibabacloud/dysmsapi-20170525": "2.0.24"封装发送短信类 发送到的短信参数写在env文件里面的 #发送短信配置 [AliyunSms] AccessKeyId "" AccessKeySecret "" signName"" templateCode"&…

⼿机客户端画K线图流程

优质博文&#xff1a;IT-BLOG-CN 一、什么是K线流程 K线图是一种用于展示金融市场价格走势的图表。它通常由四个关键价格点组成&#xff0c;即开盘价、收盘价、最高价和最低价。K线图的流程可以简单概括为以下几个步骤&#xff1a; 【1】收集数据&#xff1a; 首先&#xff0c…