当前位置: 首页 > news >正文

<JavaEE> Thread线程类 和 Thread的常用方法

目录

一、Thread概述

二、构造方法

三、常用方法

1.1 getId()、getName()、getState()、getPririty()

1.2 start()

1.3 isDaemon()、setDaemon()

1.4 isAlive()

1.5 currentThread()

1.6 Interrupt()、interrupted()、isInterrupted()

1.6.1 方法一:添加共享的标志位

1.6.2  方法二:使用内置的标志位

1.6.3 Java中终止线程不是强制性的

1.7 sleep()

1.8 join()


一、Thread概述

        Thread类是JVM用于管理线程的类,每一个线程都与一个唯一的Thread对象相关联,即每个执行流都由一个Thread对象进行描述,这些对象被JVM组织,用于线程调度和管理。

二、构造方法

构造方法说明
Thread()创建线程对象
Thread(Runnable target)使用Runnable接口实现类对象,创建线程对象
Thread(String name)创建线程对象,并为线程对象命名
Thread(Runnable target, String name)使用Runnable接口实现类对象,创建线程对象,并为线程对象命名
Thread(TreadGroup group, Runnable target)指定线程组,使用Runnable接口实现类对象,创建线程对象

三、常用方法

常用方法说明
getId()获取线程ID
getName()获取线程名
getState()获取线程状态
getPririty()获取线程优先级
start()启动线程
isDaemon()判断线程是否为后台线程(守护线程)
setDaemon()设定线程是否为后台线程(守护线程)
isAlive()判断线程是否“存活”
currentThread()获取当前线程的引用
Interrupt()终止一个线程
interrupted()判断当前线程标志位状态
isInterrupted()判断对象线程标志位状态
sleep()休眠线程
join()阻塞线程

1.1 getId()、getName()、getState()、getPririty()

getId()
获取线程ID,ID是线程的唯一标识,由JVM自动分配并确保唯一性。
getName()
获取线程名,线程名可以自动生成,也可以自定义。线程名可以重复
getState()
获取线程状态,线程的状态有就绪、阻塞等。Java中现成的状态使用枚举保存,可以通过遍历枚举获得所有状态的描述

阅读指针 -> 《Java中线程有多少种状态(State)?》

链接生成中..........

getPririty()
获取线程优先级,优先级高的线程理论上更容易被调度使用,但是在Java中优先级的效果并不明显。

操作演示:

class MyThread extends Thread{@Overridepublic void run() {for(int i=0;i<5;i++){System.out.println("这是MyThread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
public class Thread_Demo6 {public static void main(String[] args){Thread thread = new MyThread();System.out.println("ID:"+thread.getId());System.out.println("线程名:"+thread.getName());System.out.println("状态:"+thread.getState());System.out.println("优先级:"+thread.getPriority());}
}

打印结果:

ID:20
线程名:Thread-0
状态:NEW
优先级:5

1.2 start()

start() 启动线程
1)通过重写Thread中的run方法可以创建一个线程对象,再通过调用start()方法,启动这个线程。此时,操作系统中的线程才真正被创建出来。
2)Thread调用start()创建出的线程,底层仍然是调用系统的API来进行创建线程的操作
3)Thread类使用start方法启动线程,对于同一个Thread对象,start方法只能调用一次,需要启动多少个线程,就需要创建多少个Thread对象。
4)start()和run()的区别在于,run方法是提供了线程需要运行的内容,而start方法才是真正让线程运行起来。

同一个Thread对象不能多次调用start方法演示:

class MyThread extends Thread{@Overridepublic void run() {for(int i=0;i<2;i++){System.out.println("这是MyThread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("MyThread-run()运行结束");}
}
public class Thread_Demo9 {public static void main(String[] args) {Thread thread = new MyThread();//第一次启动线程thread;thread.start();//第二次启动线程thread;thread.start();}
}

打印结果:

Exception in thread "main" java.lang.IllegalThreadStateException
    at java.lang.Thread.start(Thread.java:708)
    at Learn_Thread.Demo9.Thread_Demo9.main(Thread_Demo9.java:32)

这是MyThread
这是MyThread
MyThread-run()运行结束


可以看到两次调用start方法,只有一次成功执行,另一次报错IllegalThreadStateException

1.3 isDaemon()、setDaemon()

isDaemon() 判断线程是否为后台线程
setDaemon() 设定线程是否为后台线程
1)daemon的意思是守护,因此也将后台线程称为守护线程。与后台线程相呼应,还有前台线程。
2)代码创建的线程,默认为前台线程。当setDaemon()方法的参数为false时,线程将被设置为前台线程,当参数为true时,线程将被设置为后台线程。
3)前台线程的运行时,将阻止进程结束;后台线程运行时,不会阻止进程结束。
4)因此为什么将后台线程称为守护线程?就是说进程需要我就在,进程不要我就走,在背后默默守护进程的线程嘛???

后台进程的执行演示:

class MyThread extends Thread{@Overridepublic void run() {for(int i=0;i<5;i++){System.out.println("这是MyThread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
public class Thread_Demo7 {public static void main(String[] args) {Thread thread = new MyThread();//设置为守护线程(后台线程);thread.setDaemon(true);//开始thread;thread.start();//main线程等待两秒后结束,此时守护线程还有代码没打印,但也随之结束了;try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("main线程结束");}
}

打印结果:

这是MyThread
这是MyThread
main线程结束


启动main线程和thread线程,在main线程sleep两秒结束线程后,可以看到thread线程的run()方法打印结果确实不是预期中的五次“这是MyThread”。这意味着thread线程也随着main线程的结束而结束了。

1.4 isAlive()

isAlive() 判断线程是否“存活”
1)Java中的线程类Thread对象实例,虽然表示一个线程,但这个实例的生命周期与系统内核中的线程的生命周期是不同的。
2)Thread对象创建了就存在,但此时如果调用isAlive()得到的结果将会是false,因为内核中的线程此时还不存在。
3)只有当调用start()启动线程之后,内核中的线程启动,调用isAlive()得到的结果才会是true。
4)当线程运行结束,系统内核中的线程也随之结束,此时虽然Thread对象还存在,但是调用isAlive()得到的结果也将是false。

5)因此,可以简单将这个方法认为是用于判断系统内核中的线程(PCB)是否存在。

从代码层面来讲,可以认为是用于判断run()方法是否执行完毕。

演示判断线程是否“存活”:

class MyThread extends Thread{@Overridepublic void run() {for(int i=0;i<2;i++){System.out.println("这是MyThread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("MyThread-run()运行结束");}
}
public class Thread_Demo8 {public static void main(String[] args) throws InterruptedException {Thread thread = new MyThread();//线程已有实例,判断isAlive();System.out.println("start前,thread是否存活:"+thread.isAlive());//启动线程,判断isAlive();thread.start();System.out.println("start中,thread是否存活:"+thread.isAlive());//等待run()执行结束,此时实例依旧存在,判断isAlive();Thread.sleep(5000);System.out.println("start结束,thread是否存活:"+thread.isAlive());}
}

打印结果:

start前,thread是否存活:false
start中,thread是否存活:true

这是MyThread
这是MyThread
MyThread-run()运行结束
start结束,thread是否存活:false

1.5 currentThread()

currentThread() 获取当前线程的引用
1)在currentThread()方法返回的打印信息中,有三个值,分别代表[线程名,线程优先级,所在线程组]。

获取线程引用操作演示:

public class Thread_Demo11 {public static void main(String[] args) {//打印main线程信息;System.out.println(Thread.currentThread());}
}

 打印结果:

Thread[main,5,main]


中括号中的三个值分别代表:线程名,线程优先级,所在线程组。

1.6 Interrupt()、interrupted()、isInterrupted()

如果想要中断(终止)一个线程,可以有多种方法,以下介绍两种:

方法一:通过共享的标志进行线程间沟通。
方法二:调用Interrupt()方法。

1.6.1 方法一:添加共享的标志位

class MyThread extends Thread{//设置共享的标志位;public volatile boolean isQuit = false;@Overridepublic void run() {//根据标志位的变化,决定后续执行;while (!isQuit){System.out.println("这是MyThread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("MyThread-run()运行结束");}
}
public class Thread_Demo10 {public static void main(String[] args) throws InterruptedException {Thread thread = new MyThread();//启动线程;thread.start();//延时两秒后更改标志位;Thread.sleep(2000);((MyThread) thread).isQuit = true;}
}

打印结果:

这是MyThread
这是MyThread
这是MyThread
MyThread-run()运行结束

1.6.2  方法二:使用内置的标志位

方法说明
public void interrupt()

如果线程处于阻塞状态,则抛出异常;

如果线程不处于阻塞状态,则终止线程。

public static boolean interrupted()判断当前线程标志位状态。
public boolean isInterrupted()判断对象线程标志位状态。
1)上文由程序员手动设置了一个共享的标志位,用于控制线程的执行。Java中也提供了相应的封装好的方法,内置了标志位。使用以上三个方法,一样可以达到控制线程的执行效果。

通过Interrupt()终止线程,然后对线程标志位状态进行判断:

class MyThread extends Thread{@Overridepublic void run() {//使用isInterrupted()判断标志位状态;while (!Thread.currentThread().isInterrupted()){System.out.println("这是MyThread");//打印当前线程标志位的状态;System.out.println(Thread.interrupted());}System.out.println("MyThread-run()运行结束");}
}
public class Thread_Demo12 {public static void main(String[] args) throws InterruptedException {Thread thread = new MyThread();thread.start();//延时两秒后更改标志位;Thread.sleep(2000);thread.interrupt();}
}

打印结果: 

......

这是MyThread
false
这是MyThread
false
这是MyThread
false
MyThread-run()运行结束


休眠两秒后,thread通过调用interrupt()方法修改了标志位,线程终止执行。

当更改标志位,但线程处于阻塞状态时:

        在更改标志位时,如果线程因为调用 wait/join/sleep 等方法而阻塞,则此时会抛出异常InterruptedException,并重置终止标志位。此时程序的后续执行通过catch子句中的异常处理方案来决定。
        如果在更改标志位时,线程非为阻塞状态,则标志位不会重置,可以通过interrupted()或isInterrupted()进行判断。
class MyThread extends Thread{@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()){System.out.println("这是MyThread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("MyThread-run()运行结束");}
}
public class Thread_Demo14 {public static void main(String[] args) throws InterruptedException {Thread thread = new MyThread();thread.start();//等待两秒后唤醒;Thread.sleep(2000);thread.interrupt();}
}

打印结果:

这是MyThread
这是MyThread
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at Learn_Thread.Demo14.MyThread.run(Thread_Demo14.java:16)

这是MyThread
这是MyThread
这是MyThread


可以看到,在抛出异常后,仍然继续打印,这意味着原先由interrupt()方法修改的标志位,在sleep唤醒时,又被重置为false了。

在异常处理中,加入更多的处理方法:

class MyThread extends Thread{@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()){System.out.println("这是MyThread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();//在异常处理中加入break,跳出循环;break;}}System.out.println("MyThread-run()运行结束");}
}
public class Thread_Demo14 {public static void main(String[] args) throws InterruptedException {Thread thread = new MyThread();thread.start();//等待两秒后唤醒;Thread.sleep(2000);thread.interrupt();}
}

打印结果:

这是MyThread
这是MyThread
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at Learn_Thread.Demo14.MyThread.run(Thread_Demo14.java:16)

MyThread-run()运行结束


线程通过interrupt()方法修改了标志位,但由于线程此时大概率处于sleep(即,阻塞状态),因此,抛出异常,并将标志位重置。

这里线程会终止,是由异常处理中的break跳出循环得到的结果。

1.6.3 Java中终止线程不是强制性的

操作系统中的API:提供了强制终止线程的操作,无论线程执行到何种程度,都强行结束线程。
Java中的的API:终止线程需要对应线程互相配合,而不是直接“剪断”。
优劣:强制结束线程的方式更“随心所欲,为所欲为”,但如果线程执行过程中被强行终止,可能导致出现一些临时性质的“错误”数据。而相互配合的线程终止,虽然使终止线程时需要考虑的事情变多了,但也使得线程的终止更“安全”,系统运行更稳定了

1.7 sleep()

方法说明
public static void sleep(long millis) throws InterruptedException

以毫秒级别的精度,指定休眠时间

public static void sleep(long millis, int nanos) throws InterruptedException以纳秒级别的精度,指定休眠时间
1)sleep()方法只能保证实际休眠时间大于等于参数设置的休眠时间。
2)sleep被提前唤醒(如被上文的interrup唤醒)时,会抛出异常,并将Thread对象的标志位重置为false。

sleep被提前唤醒时,为什么要重置标志位?

sleep重置标志位,可以给程序员更多的“可操作空间”。

通过抛出异常,处理异常,程序的后续执行可以且不仅可以让线程立即结束,增加了代码的灵活性。

1.8 join()

join() 等待线程结束
join(long millis) 等待线程结束,指定最长等待时间
join(long millis, int nanos) 等待线程结束,以纳秒级别的精度指定最长等待时间
1)由于随即调度,抢占式执行,多线程的执行顺序是不确定的。但是通过应用程序中的API,可以影响到线程的执行顺序。
class MyThread extends Thread{@Overridepublic void run() {for(int i=0;i<5;i++){System.out.println("这是MyThread");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("MyThread-run()运行结束");}
}
public class Thread_Demo13 {public static void main(String[] args) throws InterruptedException {Thread thread = new MyThread();thread.start();//让主线程阻塞,保证MyThread先运行完;thread.join();System.out.println("在MyThread结束后打印");}
}

打印结果:

这是MyThread
这是MyThread
这是MyThread
这是MyThread
这是MyThread
MyThread-run()运行结束
在MyThread结束后打印


可以看到,main线程中的“在MyThread结束后打印”确实是在thread线程结束后才打印的。


阅读指针 -> 《线程安全(重点!!)》

链接生成中..........

相关文章:

<JavaEE> Thread线程类 和 Thread的常用方法

目录 一、Thread概述 二、构造方法 三、常用方法 1.1 getId()、getName()、getState()、getPririty() 1.2 start() 1.3 isDaemon()、setDaemon() 1.4 isAlive() 1.5 currentThread() 1.6 Interrupt()、interrupted()、isInterrupted() 1.6.1 方法一&#xff1a;添加共…...

Linux加强篇004-Vim编辑器与Shell命令脚本

目录 前言 1. Vim文本编辑器 1.1 编写简单文档 1.2 配置主机名称 1.3 配置网卡信息 1.4 配置软件仓库 2. 编写Shell脚本 2.1 编写简单的脚本 2.2 接收用户的参数 2.3 判断用户的参数 3. 流程控制语句 3.1 if条件测试语句 3.2 for条件循环语句 3.3 while条件循环语…...

【shell脚本】常见的shell脚本面试题目

1、请用shell脚本for,while,until这三种方式写出输出1到100的所有偶数的方法。 sum=0;for((i=0;i<=100;i+=2));do let sum+=i;done;echo $sum sum=0;i=0;while [ $i -le 100 ];do let sum+=i;let i+=2;done;echo $sum sum=0;i=0;until [ $i -gt 100 ];do let sum+=i;let i+…...

Android设计模式--外观模式

弈之为术&#xff0c;在人自悟 一&#xff0c;定义 外观模式要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。提供一个高层次的接口&#xff0c;使得子系统更易于使用。 外观模式在开发中的使用频率是非常高的&#xff0c;尤其是在第三方的SDK里面&#xff0…...

03_MySQL基本SQL语句讲解

#课程目标 能够创建、删除数据表能够对表里的数据记录进行增加、删除、修改、查询操作能够创建、删除用户能够给用户授权并回收权限了解delete和truncate语句的区别 #一、数据库基本操作 ##1、查看数据库相关信息 mysql> show databases; 查看所有数据库 mysql>…...

【C语法学习】28 - 字符测试函数

文章目录 1 isalnum()函数2 isalpha()函数3 islower()函数4 isupper()函数5 isdigit()函数6 isxdigit()函数7 iscntrl()函数8 isgraph()函数9 isspace()函数10 isblank()函数11 isprint()函数12 ispunct()函数13 tolower()函数14 toupper()函数 1 isalnum()函数 isalnum()函数…...

极兔快递查询,极兔快递单号查询,对需要的单号记录进行备注

批量查询极兔快递单号的物流信息&#xff0c;对需要的快递单号记录进行备注。 所需工具&#xff1a; 一个【快递批量查询高手】软件 极兔快递单号若干 操作步骤&#xff1a; 步骤1&#xff1a;运行【快递批量查询高手】软件&#xff0c;并登录 步骤2&#xff1a;点击主界面左…...

树的序列化与反序列化

1 序列化与反序列化 二叉树的序列化与反序列化 1.1 实现思路 方式一&#xff1a;前序遍历 通过前序遍历方式实现二叉树的序列化将结果存入队列中要注意空节点也要存null 方式二&#xff1a;层序遍历 层序遍历也是用队列实现注意从左到右&#xff0c;遇到空节点存null 1.2 …...

定长子网划分和变长子网划分问题_二叉树解法_通俗易懂_配考研真题

引入:定长子网划分和变长子网划分的基本概念 定长子网划分和变长子网划分的基本概念 目前常用的子网划分&#xff0c;是基于CIDR的子网划分&#xff0c;也就是将给定的CIDR地址块划分为若干个较小的CIDR地址块。 定长子网划分: 使用同一个子网掩码来划分子网&#xff0c;因…...

ruoyi 前后分离部署502

ruoyi 前后分离部署502 我使用了nginx部署前端&#xff0c;使用docker部署。nginx文件如下&#xff1a; server {listen 8086; #设置端口listen [::]:8086; #设置端口server_name localhost;#access_log /var/log/nginx/host.access.log main;location / {root /…...

【Python】多年数据分成不同sheet

需求&#xff1a; excel文件中包含多年数据&#xff0c;其中一列列名为“年”&#xff0c;要保存一个新excel&#xff0c;将年数值不同的行保存在不同的sheet文件中&#xff0c;每个sheet文件第一行仍为原数据第一行&#xff0c;并且每个sheet名为对应的年的值。 拆分年份数据…...

Cache学习(3):Cache地址映射(直接映射缓存组相连缓存全相连缓存)

1 Cache的与存储地址的映射 以一个Cache Size 为 128 Bytes 并且Cache Line是 16 Bytes的Cache为例。首先把这个Cache想象成一个数组&#xff0c;数组总共8个元素&#xff0c;每个元素大小是 16 Bytes&#xff0c;如下图&#xff1a; 现在考虑一个问题&#xff0c;CPU从0x0654…...

GIT | 基础操作 | 初始化 | 添加文件 | 修改文件 | 版本回退 | 撤销修改 | 删除文件

GIT | 基础操作 | 初始化 | 添加文件 | 修改文件 | 版本回退 | 撤销修改 | 删除文件 文章目录 GIT | 基础操作 | 初始化 | 添加文件 | 修改文件 | 版本回退 | 撤销修改 | 删除文件前言一、安装git二、git基本操作2.1 初始化git2.2 配置局部生效2.3 配置全局生效 三、认识工作区…...

HCIA-RS基础-距离矢量路由协议

前言&#xff1a; 动态路由协议根据寻径方式可以分为距离矢量路由协议和链路状态路由协议。本文将详细介绍距离矢量路由协议的原理&#xff0c;并阐述其中一个重要概念——路由环路&#xff0c;同时介绍如何避免路由环路的方法。通过学习本文&#xff0c;您将能够深入理解距离矢…...

Python与设计模式--简单工厂模式

2-Python与设计模式–简单工厂模式 一、快餐点餐系统 想必大家一定见过类似于麦当劳自助点餐台一类的点餐系统吧。在一个大的触摸显示屏上&#xff0c;有三类可以选择的上餐品&#xff1a; 汉堡等主餐、小食、饮料。当我们选择好自己需要的食物&#xff0c;支付完成后&#x…...

四、防火墙-NAT Server

学习防火墙之前&#xff0c;对路由交换应要有一定的认识 NAT Server1.1.基本原理1.2.多出口场景下的NAT Server1.3.源进源出 —————————————————————————————————————————————————— NAT Server 一般对用户提供一些可访问的…...

Rust - cargo项目里多个二进制binary crate的编译运行

目录 foo - Cargo.toml - src - - main.rs - - bin - - - other-bin.rs将除默认入口文件外待作为二进制crate处理的文件放在src/bin目录下 方法一&#xff1a; 命令行增加配置项 --bin xxx cargo run --bin foo // 注意! 这里是包名&#xff0c;不是main cargo run --bin o…...

python爬虫教程:selenium常用API用法和浏览器控制

文章目录 selenium apiwebdriver常用APIwebelement常用API 控制浏览器 selenium api selenium新版本(4.8.2)很多函数&#xff0c;包括元素定位、很多API方法均发生变化&#xff0c;本文记录以selenium4.8.2为准。 webdriver常用API 方法描述get(String url)访问目标url地址&…...

2024年天津天狮学院专升本食品质量与安全专业《分析化学》考纲

2024年天津天狮学院食品质量与安全专业高职升本入学考试《分析化学》考试大纲 一、考试性质 《分析化学》专业课程考试是天津天狮学院食品质量与安全专业高职升本入学考试 的必考科目之一&#xff0c;其性质是考核学生是否达到了升入本科继续学习的要求而进行的选拔性考试。《…...

2023年亚太地区数学建模大赛 C 题

我国新能源电动汽车的发展趋势 新能源汽车是指以先进技术原理、新技术、新结构的非常规汽车燃料为动力来源&#xff08;非常规汽车燃料指汽油、柴油以外的燃料&#xff09;&#xff0c;将先进技术进行汽车动力控制和驱动相结合的汽车。新能源汽车主要包括四种类型&#xff1a;…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...