线程和进程(juc)

线程

一:概念辨析

1:线程与进程

进程:

1:程序由指令和数据组成,指令要执行,数据要读写,就需要将指令加载给cpu,把数据加载到内存,同时程序运行时还会使用磁盘,网络等资源。进程就是负责管理内存,加载指令,管理io的;

2:当一个程序运行时就会将程序的相关代码加载到内存中,这就开启了一个进程;

3:一个程序的实例就是进程,有的程序可以有多个实例进程,有的程序只能有一个实例进程;


线程:

1:一个进程内会有一个或多个线程

2:一个线程就是一个指令流,将指令一条条按照顺序加载给cpu执行;

3:在java中,线程是最小调度单位,进程是最小资源管理单位。在windows中进程是不活动的只是作为线程的容器;


线程和进程对比:

1:进程是相对独立的,线程存在于进程,是进程的一个子集;

2:进程有共享的资源,如共享的内存;

3:进程间的通信,分为同一个计算机和不同计算机:

同一个计算机进行通信较为简单,称为ipc;

不同计算机的进程进行通信需要借助于网络,并且遵守相同的协议如http;

4:线程间通信较为简单,因为他们共享进程的资源;

5:线程更轻量,线程切换上下文比进程切换上下文的成本更低;

2:并发和并行的概念:

并发:在单核cpu下线程实际上是串行执行的,操作系统中有个组件叫任务调度器,它会将cpu的时间片轮流交给不同的线程使用,由于时间片很短,cpu在不同的线程进行切换人类感知不到,所以就会感觉是同时运行的。总结一下就是:微观串行,宏观并行

像这种,线程轮流使用cpu的情况就叫做并发;

而在多核cpu下,每个核都可以调度线程,这个时候就是并行的;

使用golang的创作者的一句话就是:并发:是同时应对多件事的能力;(deal with)

并行:是同时做多件事的能力;(do)

二:应用

1:异步调用:

同步调用:需要等待结果返回才能执行下面的代码;

异步调用:无需等待结果的返回就能执行下面的代码;

2:提升效率:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意单核cpu使用多线程与单核cpu使用单线程的性能差距不是很大;

多核cpu和单核cpu执行的性能有很大差别;

三:创建

1:使用thread的内部类

public static void main(String[] args) {Thread t=new Thread(){@Overridepublic void run() {log.debug("new thread");}};t.setName("t1");t.start();log.debug("main");
}

t.setName(“t1”);来给线程命名。run方法指定要执行的任务,start启动线程;

2:使用runnable配合thread

将线程和任务分开:runnable来定义任务,thread创建线程:

public static void main(String[] args) {Runnable runnable= new Runnable(){@Overridepublic void run() {log.debug("running");}};Thread thread = new Thread(runnable);thread.setName("t1");thread.start();log.debug("running");
}

java8之后可以使用lamda表达式来简化语句:

public static void main(String[] args) {/* Runnable runnable= new Runnable(){@Overridepublic void run() {log.debug("running");}};*/Runnable runnable =() ->log.debug("running");Thread thread = new Thread(runnable);thread.setName("t1");thread.start();log.debug("running");
}

或者:

public static void main(String[] args) {/* Runnable runnable= new Runnable(){@Overridepublic void run() {log.debug("running");}};*//*   Runnable runnable =() ->log.debug("running");*/Thread thread = new Thread(()->log.debug("running"),"t1");/*thread.setName("t1");*/thread.start();log.debug("running");
}

3:使用futureTask配合thread

public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask<Integer> integerFutureTask = new FutureTask<Integer>(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {log.debug("running");return 100;}});Thread thread=new Thread(integerFutureTask,"t1");thread.start();log.debug("{}",integerFutureTask.get());}

futuretask继承了runnable接口,futuretask能够接收callable参数;

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

调用get方法时会阻塞等待,等待线程执行完毕然后返回结果;

四:查看

1:windows

window查看进程:

  • 使用任务管理器查看
  • 命令行:tasklist:查看所有进程
  • 杀死进程:taskkill

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2:linux

linux查看进程:

  • ps命令,结合管道运算符。
  • top命令动态的查看进程;

杀死进程:

  • kill 【进程id】

查看线程:

  • top -H -p 【进程id】

-H表示查看线程,-p指定进程id;

3:java

  • 查看进程:jps
  • 查看线程:jstack 【进程id】

五:原理

上下文切换

  • 什么是线程的上下文切换:

    当cpu暂停执行当前线程,开始执行下一个线程的时候会产生上下文切换;

  • 什么情况下会导致上下文切换

    1:cpu的时间片用完

    2:垃圾回收

    3:优先级更高的线程执行;

    4:主动调用一些方法如sleep,yield,join,wait,lock等

    当上下文切换时就需要保存当前线程的状态,并且恢复另一个线程的状态。jvm有一个组件叫程序计数器,它的作用是来记录下一条指令的执行地址,程序计数器是线程私有的;

    保存线程的状态不止程序计数器,还需要保存虚拟机栈中的栈帧信息;

    频繁的上下文切换会影响性能;

六:常见方法

1:start和run方法

start:

public static void main(String[] args) {new Thread(()->log.debug("start"),"t1").start();
}

结果:

16:20:03.992 [t1] DEBUG org.example.Field.test1 - start

run:

public static void main(String[] args) {new Thread(()->log.debug("run"),"t1").run();
}

结果:

16:22:07.587 [main] DEBUG org.example.Field.test1 - run

可以看到run没有创建一个新的线程,没法达到异步调用的效果;start可以;

start不能调用多次,不然会报错。

2:sleep

1:状态:
public static void main(String[] args) {Thread t1 = new Thread(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}}, "t1");t1.start();log.debug("state:{}",t1.getState());try {Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}log.debug("state:{}",t1.getState());
}

输出:

16:32:08.998 [main] DEBUG org.example.Field.test2 - state:RUNNABLE
16:32:09.512 [main] DEBUG org.example.Field.test2 - state:TIMED_WAITING

可以看到,调用sleep方法之后线程会进入time-waiting状态;

那个线程里调用sleep,那个线程就休眠

2:打断

调用interrupt方法可以打断休眠的线程,但是会抛出异常:

public static void main(String[] args) {Thread t1 = new Thread(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}}, "t1");t1.start();log.debug("state:{}",t1.getState());try {Thread.sleep(500);} catch (InterruptedException e) {throw new RuntimeException(e);}t1.interrupt();log.debug("state:{}",t1.getState());
}

结果:

16:36:26.912 [main] DEBUG org.example.Field.test2 - state:RUNNABLE
16:36:27.416 [main] DEBUG org.example.Field.test2 - state:TIMED_WAITING
Exception in thread "t1" java.lang.RuntimeException: java.lang.InterruptedException: sleep interruptedat org.example.Field.test2.lambda$main$0(test2.java:18)at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.InterruptedException: sleep interruptedat java.base/java.lang.Thread.sleep(Native Method)at org.example.Field.test2.lambda$main$0(test2.java:16)... 1 more
3:yield和sleep的区别

调用yield后线程的状态会从running状态转变为runnable就绪状态状态,然后去调用其他线程;具体的实现依赖于操作系统的任务调度器

和sleep的区别是,调用sleep进入time-wait状态不会被cpu调用,而调用yield进入就绪状态还是有可能被cpu调用的;

3:线程优先级

  • 线程的优先级会提示调度器优先执行该线程,但是只是一个提示,调度器可以忽略;
  • 当cpu较忙时会给优先级高的线程分配较长的时间片,cpu较闲时,优先级几乎没有作用;

4:join

join:等待线程运行结束;

join(时间):设置最大等待时间,如果超过最大等待时间则不再等待,如果没超过就执行完毕直接返回;

5:interrupt

打断线程

1:打断阻塞:

打断sleep,wait,join的线程;

打断后会抛出异常;

然后打断标记会变成true;

2:打断正常:

打断正常的线程不会使线程停止运行,只会将打断标记变为true;

public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {}}, "t1");thread.start();Thread.sleep(1000);log.debug("interrupt");thread.interrupt();log.debug("is,{}",thread.isInterrupted());
}
18:43:44.479 [main] DEBUG org.example.Field.test3 - interrupt
18:43:44.481 [main] DEBUG org.example.Field.test3 - is,true

但是会一直执行;

可以进行判断然后打断线程:

public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {Thread thread1 = Thread.currentThread();if (thread1.isInterrupted()) {log.debug("被打断了");break;}}}, "t1");thread.start();Thread.sleep(1000);log.debug("interrupt");thread.interrupt();log.debug("is,{}",thread.isInterrupted());
18:48:49.671 [main] DEBUG org.example.Field.test3 - interrupt
18:48:49.672 [t1] DEBUG org.example.Field.test3 - 被打断了
18:48:49.672 [main] DEBUG org.example.Field.test3 - is,true
``

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Java基础集合(Map)

存储特点 以键值对的形式存储, 一个元素由两个值组成 键(K-key): 无序, 无下标, 元素不可重复 值(V-value): 无序, 无下标, 元素可以重复 常用实现类 HashMap JDK1.2 底层哈希表实现 线程不安全, 效率高 LinkedHashMap JDK1.2 是HashMap的子类, 底层哈希表实现 线程不安全…

NEXT开发应用质量建议与测试指南

随着鸿蒙原生开发如火如荼的进展&#xff0c;NEXT对应用的质量提出了更高的要求。 NEXT的应用质量分为2个部分内容&#xff1a; ⚫ 体验质量&#xff1a; 功能数据完备、基础体验、HarmonyOS特征增强体验 ⚫ 内容合规&#xff1a; 资质、内容、广告、付费、开发者行为等 单元测…

java应用cpu占用过高故障排除

首先一定要清楚&#xff1a;java应用造成cpu过高的主要原因 1&#xff1a;一般是线程一直处于可运行&#xff08;Runnable&#xff09;状态&#xff0c;通常这些线程在执行无阻塞操作、循环、正则或纯粹的计算等任务 2&#xff1a;另一个可能造成CPU高的原因是频繁GC&#xff…

CPU是如何执行任务的?

你清楚下面这几个问题吗&#xff1f; 有了内存&#xff0c;为什么还需要 CPU Cache&#xff1f; CPU 是怎么读写数据的&#xff1f; 如何让 CPU 能读取数据更快一些&#xff1f; CPU 伪共享是如何发生的&#xff1f;又该如何避免&#xff1f; CPU 是如何调度任务的&#x…

最短路径算法(Dijkstra算法 + Bellman-Ford 算法 + Floyd-Warshall算法)

最短路径算法 完整版万字原文见史上最全详解图数据结构 1. Dijkstra算法&#xff08;单源最短路径&#xff09;&#xff08;无负权边图&#xff09; 算法原理 1. Dijkstra 算法通过 贪心策略 计算从一个源顶点到其他所有 顶点的最短路径。2. 时间复杂度为 O(V^2)&#xff08…

pyqt6事件概要

例子&#xff1a; 利用qtdesigner建立闹钟 python代码 # 导入所需要的文件 from PyQt6.QtGui import QIcon, QPixmap from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QListWidgetItem from PyQt6 import uic from PyQt6.QtCore import Qt, QTime imp…

位运算符I^~

&运算&#xff1a;上下相等才是1&#xff0c;有一个不同就是0 |运算&#xff1a;只要有1返回的就是1 ^(亦或)运算&#xff1a;上下不同是1&#xff0c;相同是0 ~运算&#xff1a;非运算&#xff0c;与数据全相反 cpu核心运算原理&#xff0c;四种cpu底层小电路 例&#xf…

【求助】Tinymce组件异常

版本号 { "tinymce/tinymce-vue": "^3.0.1", "tinymce": "^5.10.9", "vue": "^2.6.10", }问题&#xff1a; 就是红框处点击后没有菜单出现&#xff0c;下面是正常的

大模型分布式训练框架——DeepSpeed

本文的主要内容是阐述DeepSpeed训练模块在跟进大模型技术中的作用&#xff0c;重点解析了RLHF在其中的应用。文中深入探讨了模型训练的关键概念&#xff0c;如显存需求、优化器迭代和混合精度训练。针对大规模模型训练&#xff0c;介绍了模型并行和流水线并行等分布式训练方法&…

跟着AI 学 AI, 开发一个ChatBot, 完整图文版__持续更新中

跟着AI 学 AI&#xff0c; 开发一个ChatBot, 完整图文版__持续更新中.记录步骤以便排查错误。 使用Python 加 Visual Studio Code&#xff0c;开发代码。 使用Flask 套件和 ngrok 工具。 Step 1 下载安装Python &#xff0c;下载完后 在CMD 测试 Python --version. 结果出现p…

Pyside6 --Qt Designer--Qt设计师--了解+运行ui_demo_1.py

目录 一、打开Qt设计师1.1 Terminal终端1.2 打开env&#xff0c;GUI虚拟环境下的scripts文件1.3 不常用文件介绍&#xff08;Scripts下面&#xff09; 二、了解Qt设计师的各个控件作用2.1 点击widget看看效果&#xff01;2.2 点击Main Window看看效果 三、编写一个简易的UI代码…

『大模型笔记』OpenAI 十二天活动第1天:o1和o1 pro

『大模型笔记』OpenAI 十二天活动第1天:o1和o1 pro 文章目录 一. 『大模型笔记』OpenAI 十二天活动第1天:o1和o1 proOpenAI的12天活动o1完整版本的发布o1 Pro模式ChatGPT Proo1的性能提升多模态输入与推理o1 Pro模式的应用模型对话与历史问题示范二. 参考文献一. 『大模型笔记…

SpringBoot 运行发生异常:java: 错误: 不支持发行版本 5

一、异常&#xff1a; 二、原因&#xff1a; 本地运行用的是JDK17&#xff0c;报错应该是项目编译配置使用的Java版本不对&#xff0c;需要检查一下项目及环境使用的Java编译版本配置。 三、解决&#xff1a;

2024.12.2——[极客大挑战 2019]Secret File 1

知识点&#xff1a;抓包 代码审计 filter伪协议 一、解题步骤 step 1 查看源代码中的信息 查看源代码发现一个php文件&#xff1a;[./Archive_room.php](http://72df1f22-85bf-47bb-b23a-efcaf88701d4.node5.buuoj.cn:81/Archive_room.php) 点进去后发现没什么用&#xff0c…

MKS EDGE Series RF Generators Power Solution 软件

MKS EDGE Series RF Generators Power Solution 软件

【汇编语言】标志寄存器(一) —— 标志寄存器中的标志位:ZF、PF、SF、CF、OF 一网打尽

前言 &#x1f4cc; 汇编语言是很多相关课程&#xff08;如数据结构、操作系统、微机原理&#xff09;的重要基础。但仅仅从课程的角度出发就太片面了&#xff0c;其实学习汇编语言可以深入理解计算机底层工作原理&#xff0c;提升代码效率&#xff0c;尤其在嵌入式系统和性能优…

【C++】priority_queue优先队列

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C的string类的priority_queue优先队列&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 1. 介绍2. 仿函数(A) 介绍(B) 控制比较逻辑 3. priority_queue和…

Python3 operator 模块

Python2.x 版本中&#xff0c;使用 cmp() 函数来比较两个列表、数字或字符串等的大小关系。 Python 3.X 的版本中已经没有 cmp() 函数&#xff0c;如果你需要实现比较功能&#xff0c;需要引入 operator 模块&#xff0c;适合任何对象&#xff0c;包含的方法有&#xff1a; o…

短视频矩阵系统开发|技术源代码部署

短视频矩阵系统通过多账号运营管理、多平台视频智能分发等功能&#xff0c;助力企业实现视频引流、粉丝沉淀和转化。 短视频矩阵系统是一种创新的营销工具&#xff0c;它整合了多账号管理、视频智能分发、数据可视化等多种功能&#xff0c;为企业在短视频领域的发展提供了强大…

YOLOV11 快速使用教程

概述 这里主要记录使用NVIDIA GPU pytorch 检测系列模型的快速使用方式&#xff0c;可以快速解决一些工业应用的问题&#xff0c;比如&#xff1a;无网、数据大需要改路径、需要记录不同实验结果等问题。 安装 参考官网&#xff0c;自己安装好Python > 3.8和pytorch >…