【JavaEE】多线程(1)

在这里插入图片描述
🎆🎆🎆个人主页🎆🎆🎆
🎆🎆🎆JavaEE专栏🎆🎆🎆
🎆🎆🎆计算机是怎么工作的🎆🎆🎆’

文章目录

  • 1.进程
    • 1.1进程的概念
    • 1.2为什么需要多进程
    • 1.3多进程的坏处
    • 2.线程
    • 2.1引入线程的原因
    • 2.2线程的属性
    • 2.3线程的代码写法
    • 2.4Thread构造方法
    • 2.5Thread的等待
    • 2.6Thread的状态

1.进程

1.1进程的概念

进程是计算机中程序执行的一个实例,是操作系统进行资源分配和调度的基本单位。每个进程都拥有独立的虚拟地址空间、执行状态、寄存器集合等,是操作系统执行多任务的基础.

1.2为什么需要多进程

在现在这个时代,动不动就是8核16线程的CPU甚至更大的CPU,不像以前一个CPU只有一个核心,但是任务又多,核心数又少,导致效率很低,但现在核心数变多了,那么任务就可以同时在多个核心下一起运行就引出了多进程的概念.

1.3多进程的坏处

每创建一次进程就需要系统分配资源(内存资源和文件资源),进程结束之后需要系统去释放资源,如果出现频繁的创建进程和结束进程,这样资源消耗巨大会导致系统响应变慢.所以我们需要引进"线程".

2.线程

2.1引入线程的原因

线程(Thread)是一个轻量级进程,与"进程"相比在创建和销毁上的开销更小,主要原因是:一个进程被创建 系统会给进程分配资源,而一个进程可以有多个线程,这些线程不需要独自一个一个被系统分配资源,它们可以共享系统为进程分配的资源,在销毁的时候也只需要销毁进程的资源即可,这样下来减少了创建与销毁的开销,线程不仅共享进程的资源,而且每一个线程都有自己的属性.

2.2线程的属性

1)ID(此处的id与系统中pcb中的id是不一样的,jvm自己单独搞了一套自己的id体系,但是本质上与pcb中的id是一一对应的)
获取方法:getId()
2)名称
获取方法:getName()
3)状态
获取方法:getState()
4)优先级
获取方法:getPriority()
虽然java提供了优先级的接口,但实际上你去修改了优先级,现象也不是很明显,这里的修改只是作为一个参考,具体还是看系统本身
5)是否后台线程
获取方法:isDaemon()
前台线程:前台线程结束了,那么这个线程就结束了,如果有多个前台线程那么等到最后一个前台线程结束了,那么这个线程就结束了
后台线程:后台线程结束了,不会影响整个线程的进度,但前台线程结束了,整个线程就结束了,那么自然后台线程也就结束了
main线程就是前台线程
还有就是像我们自己创建的线程默认情况下也是前台线程,可以通过setDaemon()方法来把线程设置后台线程
后台线程比如有gc(垃圾回收——对内存还有文件资源的回收) 是一个周期性持续执行的线程,不会自己主动结束
这是将前台线程设置为后台线程代码:

public class Deom7 {public static void main(String[] args) {Thread t1 = new Thread(() -> {for (int i = 0; i < 10; i++) {System.out.println("打印thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.setDaemon(true);t1.start();}}

注意:
nterrupt和isInterruptted方法
Thread.currentThread()这个是一个static方法,这个方法可以获取到当前线程也就是t这个引用
isInterruptted()方法就是线程内置标志位
true 表示线程要终止
false 表达线程要继续执行
调用这个interrupt()方法:
可以将标志位修改位true还可以唤醒sleep等阻塞
但是调用这个方法之后,如果程序中有sleep方法那么不仅仅会唤醒sleep而且还会清除修改的标志位,此处的清除标志位的目的就是将控制权交给程序猿
如果没有sleep,那么就是一个简简单单的修改标志位
6)是否存活
获取方法:isAlive()
jvm提供的Thread类中的线程与系统中的PCB的生命周期是不一样的
当我已经实例化Thread对象的时候,此时的系统还没有创建PCB
当我们执行到了start()方法的时候,系统才创建PCB
7)是否被中断
获取方法:isInterrupted()

2.3线程的代码写法

总共有五种常见的写法:
1.创建Thread子类
创建一个子类继承于Thread类重写父类的run方法

class MyThread extends Thread {@Overridepublic void run() {while(true) {System.out.println("打印Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
public class Deom1 {public static void main(String[] args) throws InterruptedException {Thread t1 = new MyThread();t1.start();while(true) {System.out.println("打印main");Thread.sleep(1000);}}

2.通过实现Runnable接口
实现接口,重写接口中的run方法,这种方法可以解耦合

class MyRunnable implements Runnable{@Overridepublic void run() {while(true) {System.out.println("打印Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
public class Deom2 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new MyRunnable());t1.start();while(true) {System.out.println("打印main");Thread.sleep(1000);}}}

3.创建匿名内部类继承Thread类

public class Deom3 {public static void main(String[] args) throws InterruptedException {new Thread() {@Overridepublic void run() {while (true) {System.out.println("打印Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}.start();while (true) {System.out.println("打印main");Thread.sleep(1000);}}
}

4.创建匿名内部类实现Runnable接口

public class Deom4 {public static void main(String[] args) throws InterruptedException {new Thread(new Runnable() {@Overridepublic void run() {while (true) {System.out.println("打印Thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}).start();while (true) {System.out.println("打印main");Thread.sleep(1000);}}}

5.使用lambda表达式

public class Deom5 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {while (true) {System.out.println("打印thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.start();while(true) {System.out.println("打印main");Thread.sleep(1000);}}
}

3,4,5这三种方式好处就是代码简洁,坏处就是可读性不高.
此处提到的run方法与start方法;
run方法:作用就是描述一个任务,然后线程实现之后去实现的任务就是这个run方法中描述的任务
start方法:作用就是创建线程和执行线程

2.4Thread构造方法

1)Thread()无参数
2)Thread(Runnable target) 使用Runnable对象创建对象
3)Thread(String name) 创建线程对象,并命名
4) Thread(Runnable target,String name)使用Runnable对象创建线程对象,并命名

2.5Thread的等待

由于线程的调度是抢占式的,所以在线程的执行顺序有不确定性,我们就需要引用一个join方法来解决。
在哪个线程中调用join方法就哪个线程阻塞等待
比如:在main线程中调用了t1.join,那么就是main线程等待阻塞,等t1线程结束之后,main线程才执行。
join不参数的属于死等,无限制的去等,这样有时候在有些场景不适用,所以还有一个有时间版本的join方法
join(long millis)
例子:
t1.join(10)被main线程调用,如果t1线程让main线程等待超过了10ms,那么main线程就不会继续等待阻塞下去,就会继续执行main线程下面的代码

使用slee控制的式"线程休眠时间 “而不是"两个代码执行的间隔时间”

main线程等t1线程:

public class Deom8 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}});t1.start();t1.join();System.out.println("main线程结束");}
}

让t2等t1线程,main线程等t1和t2线程:

public class Deom9 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {try {System.out.println("t1线程结束");Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}});Thread t2= new Thread(() -> {try {t1.join();System.out.println("t2线程结束");Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}});t1.start();t2.start();t2.join();System.out.println("main线程结束");}}

main线程只等待t1线程3秒,但t1线程需要5秒执行时间,但时间一到main线程也不会等待t1:

public class Deom10 {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("t1线程结束");});t1.start();t1.join(3000);System.out.println("main线程结束");}
}

2.6Thread的状态

1.NEW Thread对象有了,但还未调用start系统内部的线程还未创建
2.TERMINATED 线程已经终止了,系统内核中的线程已经销毁,但对象还在
3.RUNNABLE 就绪状态 指这个线程要么已经在CPU中执行,要么随时都可以被CPU调度
4.WAITING 死等进入阻塞
5.TIMED_WAITING 带有时间的等
6.BLOCKED 进行锁竞争的时候产生的阻塞

绘图描述(简化):
在这里插入图片描述

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

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

相关文章

neutron学习小结

概述 基于yoga版本学习neutron&#xff0c;通过源码、官方文档、部署环境进行学习 neutron-dhcp-agent neutron.agent.dhcp_agent.main 创建server&#xff0c;调oslo_service launch server&#xff0c;最后实际调了server的start方法 neutron.service.Service.start Serv…

蓝桥杯--杂题

1.贪心&#xff1a; 我们先枚举哪个国家赢了&#xff0c;然后再建一个数组排序即可。 下面是AC代码&#xff1a; #include<bits/stdc.h> using namespace std; #define int long long int n; int a[100010],b[100010],c[100010]; bool cmp(int a,int b) {return a>b…

服务器数据恢复—EqualLogic存储硬盘灯亮黄色的数据恢复案例

服务器数据恢复环境&#xff1a; 一台某品牌EqualLogic PS 6011型号存储&#xff0c;底层有一组由16块SAS硬盘组建的RAID5阵列&#xff0c;上层存储空间划分了4个卷&#xff0c;格式化为VMFS文件系统&#xff0c;存放虚拟机文件。 服务器故障&#xff1a; 存储设备上两块硬盘指…

微信小程序发送订阅消息

小程序后台。订阅消息里面&#xff0c;新建一个消息模板 小程序代码&#xff0c;登录后&#xff0c;弹出订阅信息 requestSubscribeMessage: function () {wx.requestSubscribeMessage({tmplIds: [-323232-32323], // 替换为你的模板IDsuccess(res) {// 用户订阅结果console.l…

第22讲:文件操作

文章目录 第22讲&#xff1a;文件操作1. 为什么使用文件2. 什么是文件2.1 程序文件2.2 数据文件2.3 文件名 3. 二进制文件和文本文件&#xff1f;4. 文件的打开和关闭4.1 流和标准流4.1.1 流4.1.2 标准流 4.2 文件指针4.3 文件的打开和关闭 5. 文件的顺序读写5.1 顺序读写函数介…

PyQt5开发笔记:1.环境搭建与界面美化

推荐视频教程&#xff1a; https://www.bilibili.com/video/BV1LT4y1e72X?p23&vd_source7ab611f3afb3d469faad93d3996f99ba 一、打开网址&#xff0c;点击下载 https://build-system.fman.io/qt-designer-download 下载后&#xff0c;点开exe 不推荐&#xff1a;http…

每周算法:次小生成树

题目链接 秘密的牛奶运输 题目描述 农夫约翰要把他的牛奶运输到各个销售点。 运输过程中&#xff0c;可以先把牛奶运输到一些销售点&#xff0c;再由这些销售点分别运输到其他销售点。 运输的总距离越小&#xff0c;运输的成本也就越低。 低成本的运输是农夫约翰所希望的…

react 动态form表单

需求在日常开发中反复写form 是一种低效的开发效率&#xff0c;布局而且还不同这就需要我们对其封装 为了简单明了看懂代码&#xff0c;我这里没有组件&#xff0c;都放在一起&#xff0c;简单抽离相信作为大佬的你&#xff0c;可以自己完成&#xff0c; 首先我们做动态form …

Gartner发布电信运营商应对持续变化的网络安全环境指南:现代云安全与网络安全的五大核心挑战

所有组织的云和网络都面临着高级威胁。作为网络安全的关键参与者&#xff0c;电信运营商的 CIO 需要了解行业面临的挑战&#xff0c;并了解应采用哪些解决方案来实现方法的现代化。 主要发现 电信运营商 (CSP) CIO 如果不能调整其安全策略来保护其环境&#xff0c;那么他们将会…

IDEA 中导入脚手架后该如何处理?

MySQL数据库创建啥的&#xff0c;没啥要说的&#xff01;自行配置即可&#xff01; 1.pom.xml文件&#xff0c;右键&#xff0c;add Maven Project …………&#xff08;将其添加为Maven&#xff09;【下述截图没有add Maven Project 是因为目前已经是Maven了&#xff01;&…

LNMP安装部署

yum -y install ncurses ncurses-devel bison cmake openssl-devel gcc gcc-c make 方法二

差旅游记|绵阳印象:与其羡慕他人,不如用力活好自己。

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 来绵阳之前同事就问: “雷工&#xff0c;能吃辣嘛&#xff1f;”。 “还行&#xff0c;能吃点辣。” “那你去了四川别说能吃点辣&#xff0c;那边的能吃点比跟你说的能吃点不太一样” 01 你好 今天打车&#xff0c;上…

「多客」圈子论坛社区交友系统开源版小程序源码|圈子社区系统

简述 社交圈子论坛系统是一种面向特定人群或特定话题的社交网络&#xff0c;它提供了用户之间交流、分享、讨论的平台。在这个系统中&#xff0c;用户可以创建、加入不同的圈子&#xff0c;圈子可以是基于兴趣、地域、职业等不同主题的。用户可以在圈子中发帖、评论、点赞等互…

抖音太可怕了,我卸载了

这两天刷短视频&#xff0c;上瘾了&#xff0c;太可怕了。 自己最近一直在研究短视频制作&#xff0c;所以下载了抖音&#xff0c;说实话&#xff0c;我之前手机上并没有抖音&#xff0c;一直在用B站。 用了两天抖音&#xff0c;我发现&#xff0c;这玩意比刷B站还容易上瘾啊…

Centos 7下的VulFocus靶场搭建详细教程

一、靶场介绍 自带 Flag 功能&#xff1a;每次启动 flag 都会自动更新&#xff0c;明确漏洞是否利用成功。带有计分功能。兼容 Vulhub、Vulapps 中所有漏洞镜像。 二、下载安装 下载 VMware 软件下载 centos镜像 三、Docker知识 学习链接&#xff1a;https://www.runoob.c…

chrome调试手机网页

前期准备 1、 PC端安装好chrmoe浏览器 2、 安卓手机安装好chrmoe浏览器 3、 数据线 原文地址&#xff1a;https://lengmo714.top/343880cb.html 手机打开调试模式 进入手机设置&#xff0c;找到开发者模式&#xff0c;然后启用USB调试 打开PC端chrome调试功能 1、点击chr…

【康耐视国产案例】AI视觉相机创新 加速商超物流数智化转型

连锁商超/零售店正面临着因消费者购物习惯改变等挑战&#xff0c;迎来了以新兴技术崛起而催生的数字化物流体系转型需求。物流行业与AI机器视觉的深度融合&#xff0c;解决了传统机器视觉识别速度慢、环境要求高、定制化部署耗时过多等痛点&#xff0c;大大提高了物流供应链的效…

GD32F470+lwip 丢包问题分析及解决

最近在用GD32和管理机之间用TCP协议开发一个功能&#xff0c;功能都没问题&#xff0c;后面跑大量发包时候的连续测试时&#xff0c;总是会出现偶发性的&#xff0c;大概几分钟到数十分钟的一次丢包。尽管在应用层做了超时机制&#xff0c;一旦超时就会重新建立socket链接并重新…

QT系列教程(6) 几种标准对话框

几种标准对话框 本文介绍几种标准对话框&#xff0c;都是Qt封装好的&#xff0c;我们先创建一个界面&#xff0c;添加几个按钮&#xff0c;然后分别在几个按钮的回调函数里添加创建不同对话框的逻辑 颜色对话框 颜色对话框用来选择颜色&#xff0c;创建后会显示各种颜色和透明…

ABB码垛机器人IRB260通讯板维修

ABB码垛机器人在现代制造业中发挥着重要作用&#xff0c;而机器人通讯板维修对于确保机器人的正常运行至关重要。 通讯板是ABB码垛机器人与控制系统之间进行数据传输的桥梁。它负责接收控制系统的指令&#xff0c;并将机器人的运行数据反馈给控制系统。如果通讯板出现故障&…