java多线程(并发)夯实之路-进程与线程深入浅出

进程与线程介绍

进程

程序由指令和数据组成,程序工作时,就会将指令加载至CPU,数据加载至内存,进程就是用来加载指令,管理内存,管理IO的。

当程序运行,磁盘加载这个程序的代码至内存,这时就开启了一个进程。

进程可以视为程序的一个实例,大部分程序能同时运行多个实例进程(记事本,浏览器),也有程序只能启动一个实例进程(网易云音乐)。

线程

一个进程之内可以有为一个或多个线程。

一个线程就是一个指令流,指令流中的一条条指令将以一定的顺序交给CPU执行。    

Java中,线程作为最小调度单位,进程作为资源分配的最小单位。window中进程是不活动的,只是作为线程的容器。

对比

两者相互独立,进程包含线程,进程拥有的资源供线程共享,进程间通信复杂,线程相对简单

(因为资源共享),线程更轻量,上下文切换成本更低。

并行并发

单核CPU下,单个CPU轮流处理多个线程,这被称为并发。

多核CPU下,多个CPU同时处理多个线程,这被称为并行(并行中也有并发)。

比喻

CPU:一座工厂。

进程:工厂的一个车间(工厂电力有限,一次只能运行一个车间)。

线程:车间的工人(车间内可以有多个工人,车间内的资源为工人们所共享)。

并行:单核CPU下,同一时间只能有一个工人工作,其他工人不能工作,但是工作一段时间后会停止工作,把时间让给另外一个工人。工人轮流工作。

并发:多核CPU下,同一时间多个工人能同时工作。

异步和同步

同步:需要等待结果返回,才能继续运行(如读取文件操作)。

异步:不需要等待结果返回,就能继续运行。

结论:为防止同步操作等待费时,可以新开一个线程进行该费时操作,避免阻塞主线程(如 tomat的异步servlet,ui程序中开新线程防止阻塞ui线程)。


多核CPU在某一情形下,开多个线程并行可以提供效率。单核仍然是轮流执行,可以实现任务间切换,但是上下文切换会耗费一段时间。IO操作不占用CPU,一般拷贝文件使用的是阻塞IO,需要一直等到IO结束,所以才有后面的非阻塞IO和异步IO优化。

创建线程

java程序启动时默认有一个主方法线程(主线程),在主线程之外创建线程可以使用如下方法:

原理:如果传入Thread对象中的Runable对象不为空,Thread对象中的run()方法将会调用 Runnable对象的run()方法,如方法2。方法1则是直接重写了Thread对象中的run方法。无论是哪个方法,都是运行run()方法。推荐方法2,使用Runnable更容易与线程池等高级API配合,让任务类脱离了Thread继承体系,更加灵活。

方法3:

FutureTask配合Thread  

FutrueTask能够接受Callable类型的参数,用来处理有返回结果的情况

多个线程运行

交替执行。

谁先谁后,不受我们控制,由底层调度器控制。

线程上下文切换(Thread Context Switch)

上下文切换原因:

线程的CPU时间片用完垃圾回收

有更高优先级的线程需要运行

线程调用了sleep,wait,lock,synchronized,yield,park,join等方法

Context  Switch发生时,操作系统会保持当前线程状态,然后恢复另一个线程状态(如下

图),Java中对应的概念就是程序计数器(Program Counter Register),它的作用是记住下一条jvm指令的执行地址,是线程私有的。

状态包括程序计数器,jvm中每个栈帧的信息(如局部变量,操作数栈,返回地址等)。频繁发生上下文切换会降低性能。

查看进程,线程的方法

windows:

任务管理器 tasklist查看线程 taskkill杀死线程

linux:

ps -fe查看所有进程

ps -fT -p <PID>查看某个进程(PID)的所有线程 kill 杀死进程

top按大写H切换是否显示线程

top -H -p <PID> 查看某个进程的所有线程

Java:

jps命令查看所有Java进程

jstack <PID>查看某个Java进程(PID)的所有线程状态

jconsole来查看某个java进程中线程的运行状况(图形界面)

常见方法

方法汇总

run vs start

调用run()方法是由主线程执行,调用start()方法由新线程执行,启动新线程必须用 start()方法。start()方法不能被多次调用。

sleep

调用sleep方法,线程会从Running状态进入Timed Waiting状态(不能分得CPU时间片)。其他线程可以用interrupt方法打断正在睡眠的方法,sleep方法会抛出interruptedException。

睡眠结束后线程未必会立刻执行。

建议用TimeUnit的sleep代替Thread中的sleep来获得更好的可读性。

sleep应用

防止CPU占用100%

没有用cpu来计算时,不要让while(true)空转浪费cpu,这时可以使用sleep和yield把cpu使用权交给其他程序

可以用wait或条件变量达到类似效果

不同的时,后两者需要加锁,并且需要唤醒操作,一般适用于进行同步的场景 sleep适用于无需同步的场景。

yield

调用yield方法,线程会从Running状态进入Runnable就绪状态(可能分得CPU时间片),然后调用其他同优先级的线程。如果这时没有同优先级的线程,将不能保证让当前线程停止。

具体实现依赖于操作系统的任务调度器。

线程优先级

线程优先级会提示(hint)任务调度器优先调度该线程。         

CPU繁忙时,优先级高的线程会获得更多时间片;CPU空闲时,优先级几乎没用。

线程的调度并不受线程优先级和yield控制,实际上是由任务调度器决定的。

join

等待某一线程运行结束才能执行接下来的代码,应用于同步。

有参的join方法可以限制等待的最长时间,最长等待时间过后,将不再等待,继续向下运行。

interrupt

线程正常运行时被打断,打断标记设为真;执行sleep,wait,join方法时被打断,会以抛出异常的方式表示被打断,打断标记设为假(清空打断标记)。

打断标记可以用来判断打断后线程是运行还是终止。

如下代码中t1将一直运行

可以使用打断标记优雅地停止线程,代码如下

interrupt打断park

park方法能使线程停止运行,使用interrupt方法打断park能使线程继续运行,打断标记设为真,之后再调用park方法线程也不会停止运行(打断标记为真park失效)

如下代码中,第二个park方法将不再生效

使用interrupted方法能清空打断标记(输出结果仍为真),第二个park方法能够再生效

不推荐使用的方法

这些方法已经过时,容易破坏同步代码块,造成线程死锁,interrupt,wait,notify取代了这些方法

主线程和守护线程

默认情况下,Java进程只会在所有线程都结束运行才结束。但有一种特殊的线程叫守护线程,在非守护线程结束后,守护线程将强制结束。

设置守护线程代码如下,t1线程将强制结束。

应用

垃圾回收器就是一种守护线程。

Tomcat中的Acceptor和Poller线程都是守护线程,所以Tomcat接收shutdown命令后,不会等它们处理完当前请求。

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

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

相关文章

应用在游戏机触摸屏中的触摸感应芯片

触屏游戏机的屏幕是由液晶屏和触控层组成的。触控层分为电容式触屏和电阻式触屏两种。电容式触屏是将悬空电极和屏幕玻璃上的电极组成静电场,当人体接近屏幕时,就会改变静电场分布,从而实现触摸的位置探测。而电阻式触屏则是利用玻璃上的两层电极之间通电形成一个电阻值,当手指…

【PHP AES加解密示例】从入门到精通,一篇文章让你掌握加密解密技术!

一、引言 随着互联网的普及&#xff0c;数据安全问题越来越受到人们的关注。在众多加密算法中&#xff0c;AES&#xff08;Advanced Encryption Standard&#xff09;因其高效、安全的特点被广泛应用。本文将通过PHP语言&#xff0c;为大家展示一个简单的AES加解密示例&#x…

计算机毕业设计-----SSH在线电影售票选座版网站平台系统

项目介绍 本项目为前后台项目&#xff0c;首先分为管理员和普通用户&#xff0c;游客。 游客可以进入首页&#xff0c;必须注册成为普通用户才能进行影片的购买。管理员和普通用户进行分权限登录&#xff0c;登录后进入不同页面。 普通用户登录后进入首页&#xff0c;首页有影…

手把手教你用 Stable Diffusion 写好提示词

Stable Diffusion 技术把 AI 图像生成提高到了一个全新高度&#xff0c;文生图 Text to image 生成质量很大程度上取决于你的提示词 Prompt 好不好。 前面文章写了一篇文章&#xff1a;一份保姆级的 Stable Diffusion 部署教程&#xff0c;开启你的炼丹之路 本文从“如何写好…

如何使用Flash模拟EEPROM

目录 1、FLASH与EEPROM简介 2、FLASH模拟EEPROM原理 2.1、EERPOM数据结构 2.2、EERPOM物理结构 在讲解这篇博文前&#xff0c;首先要明白为什么使用Flash存储来模拟EEPROM&#xff1f; 主要有以下几个原因&#xff1a; 成本效益&#xff1a;许多微控制器(MCU)和系统芯片(SoC)内…

MySQL题目示例

文章目录 1.题目示例 1.题目示例 09&#xff09;查询学过「张三」老师授课的同学的信息 SELECT s.*, c.cname, t.tname, sc.score FROM t_mysql_teacher t, t_mysql_course c, t_mysql_student s, t_mysql_score sc WHERE t.tid c.tid AND c.cid sc.cid AND sc.sid s.sid …

如何使用统计鸟网站统计分析网站流量来源?

统计鸟官网地址&#xff1a;https://www.tongjiniao.com/ 站长必备&#xff01;网站数据统计&#xff0c;流量监测平台 提供网站数据统计分析、搜索关键词、流量访问来源等服务 深入分析用户点击习惯&#xff0c;为智能化运营网站提供更好的用户体验 目录 一、注册账号信息 二…

Web3的应用发展及其影响

Web3&#xff0c;又被称为去中心化Web&#xff0c;是互联网发展的一个阶段&#xff0c;其核心特点是数据的去中心化和用户自主权。近年来&#xff0c;随着区块链技术的不断成熟&#xff0c;Web3的应用也得到了广泛的关注和发展。在这篇文章中&#xff0c;我们将深入探讨Web3目前…

【Win11】电脑正常联网浏览器却打不开???

今天本来打算打开B站开始今天的学习之旅&#xff0c;一打开却发现。。。 我还以为电脑没联网但是微信可以聊天发消息然后我在dos窗口测了下网络是正常联通的 然后我开始慌了&#xff0c;这阳光明媚的一天不看B站学习怎么行&#xff0c;然后我就开始在百度上冲浪找解决方案&…

【小程序开发需要多少钱?】

哈喽&#xff0c;大家好&#xff0c;这里是智创开发。 我们今天聊聊开发一个小程序需要多少钱。 由于自己组建团队来开发小程序成本过高&#xff0c;大品牌的企业一般都不会这么搞&#xff0c;所以我们今天只谈假如我有需求&#xff0c;找服务商来全程搞定的费用大致是多少。和…

Spark---RDD持久化

文章目录 1.RDD持久化1.1 RDD Cache 缓存1.2 RDD CheckPoint 检查点1.3 缓存和检查点区别 2.RDD分区器2.1 Hash 分区&#xff1a;2.2 Range 分区&#xff1a;2.3 用户自定义分区 1.RDD持久化 在Spark中&#xff0c;持久化是将RDD存储在内存中&#xff0c;以便在多次计算之间重…

浅谈6种流行的API架构风格

前言 API在现代软件开发中扮演着重要的角色&#xff0c;它们是不同应用程序之间的桥梁。编写业务API是日常开发工作中最常见的一部分&#xff0c;选择合适的API框架对项目的成功起到了至关重要的作用。本篇文章将浅谈一下当前6种流行的API架构风格的优点、缺点以及适用场景。 6…