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

[Java EE] 多线程(一) :线程的创建与常用方法(上)

1. 认识线程

1.1 概念

1.1.1 什么是线程

⼀个线程就是⼀个"执⾏流".每个线程之间都可以按照顺序执⾏⾃⼰的代码.多个线程之间"同时"执⾏
着多份代码.

还是回到我们之前的银⾏的例⼦中。之前我们主要描述的是个⼈业务,即⼀个⼈完全处理⾃⼰的业务。我们进⼀步设想如下场景:
⼀家公司要去银⾏办理业务,既要进⾏财务转账,⼜要进⾏福利发放,还得进⾏缴社保。
如果只有张三⼀个会计就会忙不过来,耗费的时间特别⻓。为了让业务更快的办理好,张三⼜找来两位同事李四、王五⼀起来帮助他,三个⼈分别负责⼀个事情(可以理解为一个进程中包含着多个线程),分别申请⼀个号码进⾏排队,⾃此就有了三个执⾏流共同完成任务,但本质上他们都是为了办理⼀家公司的业务。
此时,我们就把这种情况称为多线程,将⼀个⼤任务分解成不同⼩任务,交给不同执⾏流就分别排队执⾏。其中李四、王五都是张三叫来的,所以张三⼀般被称为主线程(MainThread)。

1.1.2 为什么要有线程

首先,“并发编程"是"刚需”.

  • 单核CPU的发展遇到了瓶颈.要想提高算例,就需要多核CPU.而并发编程能更充分利用多核CPU
    资源
    .可以把一个任务拆解为多个部分,分配给不同的CPU核心来完成.
  • 其次虽然多进程也可以实现并发编程,但是线程比进程更加轻量.
    • 创建线程比创建进程快.
    • 销毁线程要比销毁进程快(上述两方面的原因都是因为每次创建进程都会分配系统资源,这种操作的开销比较大,而线程就可以对资源进程沿用)
    • 调度线程比调度进程快.(通过PCB中的线程调度属性来支持)

1.1.3 PCB与线程

严格意义上来说,一个PCB是描述一个线程的,而进程是若干个PCB合起来描述的.

  1. pid:每个线程都不同.(线程id)
  2. 内存指针:同一进程相同,线程之间不一样.
  3. 文件描述符表:同一进程相同,线程之间不一样.(由于同一进程调度的系统文件和使用的内存资源都是一样的,所以2,3一样)
  4. 线程调度属性:由于它是支持线程调度的一个属性,所以很明显不同线程之间一定不一样,他是每个线程独有的属性.
  5. tgid:同一进程中的线程之间都是一样的.(进程id)

我们拿一个"合租"的例子来说明上述问题
比如我们合租一间房子,客厅,卫生间,厨房等空间都是公共区域,相当于上述PCB中的内存指针和文件描述符表还有tgid,每个线程之间共享着内存空间和系统文件.每个卧室之间是每个人独有的空间,每个人的房间都不一样,就像上述的pid,线程调度属性.
在这里插入图片描述

1.1.4 线程与进程的区别(重点面试题,面试必考)

  • 进程包含线程,每个进程至少有一个进程存在,就是主线程.
  • 进程和进程之间不共享内存空间和文件资源,即它们的内存指针和文件描述符表不一样.而同一进程的线程之间共享内存空间和文件资源.
  • 进程是资源分配的基本单位(分配内存空间和文件资源),线程是执行调度的基本单位(创建线程调度属性).
  • 一个进程崩溃不会影响到其他进程,一个线程崩溃可能会影响其他进程,连同其他线程一起崩溃.

[举例]
下面有请我们的助教,蔡徐坤老师.
全民制作人们大家好,我是练习时长两年半的个人练习生cxk,喜欢Java,数据结构,数据库,music

  1. 坤坤要进一间房中吃只因,创建了一个带有一个主线程的进程:
    在这里插入图片描述
  2. 由于房间中的只因实在太多了,有100只,于是便分配到两个房间来有两个坤坤吃:
    在这里插入图片描述
  3. 但是由于在盖一间房(创建一个新的进程)的开销实在是太大了,所以我们让好多个坤坤(好多个线程)进同一个房间吃只因.(创建好多个线程),这样就会节省开销.
    在这里插入图片描述
  4. 但是此时,有两个坤坤产生了冲突,它们在抢一只只因大腿,它们都想吃.
    在这里插入图片描述
  5. 此时,旁边的坤坤来劝架(鸡哥算了算了),劝住了.大家继续吃只因.(进程继续运行)
    在这里插入图片描述
  6. 如果没劝住,就直接掀桌(╯‵□′)╯︵┻━┻了,大家谁都别吃了,进程也就挂掉了.
    在这里插入图片描述

1.2 创建多线程

注:下面在主方法中创建的线程属于主线程,在程序执行之后会自动启动线程.建议看完后面的1.3的一部分内容之后再来看这里.run()方法,start()方法,构造,sleep()方法都在后面.

  1. 通过继承Tread类,并在主线程创建线程对象.
public class MyTread extends Thread{@Overridepublic void run() {while (true){System.out.println("hello tread");try {Thread.sleep(1000);} catch (InterruptedException e) {//注意调用sleep方法需要抛出异常throw new RuntimeException(e);}}}public static void main(String[] args) {Thread thread = new MyTread();thread.start();while (true){System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
  1. 通过实现Runnable接口,并在主线程为Tread的构造方法传入这个类的引用来创建线程对象.
public class MyTread1 implements Runnable{@Overridepublic void run() {while (true){System.out.println("hello tread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}public static void main(String[] args) {Thread thread = new Thread(new MyTread());thread.start();while (true){System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
  1. 通过匿名内部类来创建线程对象.第一种是直接重写Tread接口中的方法,第二种是给Tread类的构造方法传入Runnable接口,并重写Runnable中的方法.
public class MyTread2 {public static void main(String[] args) {Thread thread = new Thread(){@Overridepublic void run() {while (true){System.out.println("hello tread");try {Thread.sleep(1000);//Tread类中的一个static方法} catch (InterruptedException e) {throw new RuntimeException(e);}}}};thread.start();while (true) {System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
public class MyTread3 {public static void main(String[] args) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {while (true){System.out.println("hello tread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}});thread.start();while (true){System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
  1. 通过创建labda表达式,这是对run方法的一种平替版本.
public class MyTread4 {public static void main(String[] args) {Thread thread = new Thread(() -> {while (true){System.out.println("hello tread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();while (true){System.out.println("hello main");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

2. Tread类及其常见方法

Thread类是JVM⽤来管理线程的⼀个类,换句话说,每个线程都有⼀个唯⼀的Thread对象与之关
联。⽤我们上⾯的例⼦来看,每个执⾏流,也需要有⼀个对象来描述,类似下图所⽰,⽽Thread类的对象就是⽤来描述⼀个线程执⾏流的,JVM会将这些Thread对象组织起来,⽤于线程调度,线程管理.
在这里插入图片描述

2.1 Tread的常见构造方法

方法说明
Tread()创建线程对象
Tread(Runnable target)使用Runnable对象来创建线程
Tread(String name)创建线程对象并命名
Tread(Runnable target,String name)使用Runnable对象来创建线程并命名
Thread t1 = new Thread();
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread("这是我的名字");
Thread t4 = new Thread(new MyRunnable(), "这是我的名字");

2.2 Tread的常见属性

属性获取方法
idgetId()
名称getName()
优先级getPriority()
状态getState()
是否是后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()

拓展:把一个线程设置为后台线程的方法是线程引用.setDaemon(true).

  • id是线程的唯一标识,不同的线程不会重复
  • 名称可以通过jconsole看到.
  • 状态表示线程当前所处的⼀个情况,下面我们会进⼀步说明.
  • 优先级高的线程理论上来说更容易被调度到.
  • 关于后台线程,我们要多唠几句:
    首先什么是前台线程,这和我们平时所知道的前台不一样,这里指的前台线程是,前台线程运行不结束,Java程序永远不会结束,后台线程是,后台即使在运行,只要前台线程全部结束,也不可以阻止Java程序结束,当然后台线程的结束也不可以对Java程序的执行产生任何影响.(如gc线程,就是Java垃圾回收线程,是周期性持续执行的后台线程)

我们下面举一个代码的例子:

public class Demo0 {public static void main(String[] args) {Thread thread = new Thread(()->{try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("tread");});thread.setDaemon(true);//把tread线程设置为后台线程thread.start();System.out.println("main is terminate");}
}

运行结果:
在这里插入图片描述
这里我们可以看到,只打印了最后main线程的一句话,由于在tread设置为了后台线程,而且在线程中sleep了1s,tread还没来得及反应,前台线程main线程就已经结束了,整个进程就结束了,后台的tread也不得不结束.

我们下面通过一个实际生活中的例子-----吃酒席来说明:

  1. 今天吃酒席,有马化腾,马云,还有一些小喽啰.
    在这里插入图片描述
    由于马云和马化腾都是大老板,掌管者整个酒席的节奏,一桌酒席是否结束,由他们说了算.它们就是前台线程,掌管者整个进程.
  2. 马云和马化腾掌管者整个酒席的节奏,它们都说结束才可以结束,要是有一个没喝好,就不可以结束.
    在这里插入图片描述
    酒席结束了,小喽啰不走也得走了.
    在这里插入图片描述
  3. 突然有一个小喽啰实在喝不动了,提前溜了.但是酒席不可以结束,马爸爸和马爹爹还没有喝好,接着喝,可见后台进程的结束并不影响进程是否结束.
    在这里插入图片描述
  • 是否存活,线程中的线程引用是否被gc回收,这里不可以理解为线程是否还在执行,两者有一定的区别.
  • 线程终端问题,后序介绍.

[未完待续…]

相关文章:

[Java EE] 多线程(一) :线程的创建与常用方法(上)

1. 认识线程 1.1 概念 1.1.1 什么是线程 ⼀个线程就是⼀个"执⾏流".每个线程之间都可以按照顺序执⾏⾃⼰的代码.多个线程之间"同时"执⾏ 着多份代码. 还是回到我们之前的银⾏的例⼦中。之前我们主要描述的是个⼈业务,即⼀个⼈完全处理⾃⼰的…...

Linux安装docker(含Centos系统和Ubuntu系统)

一、Centos系统 1. 卸载旧版本依赖 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 2. 设置仓库 安装所需的软件包。yum-utils 提供了 yum-config-manager &…...

【第十五届蓝桥杯大赛软件赛省赛】———— C/C++ 大学B组

蓝桥杯2024年15届省赛b组原题献上...

Redis+lua脚本限制ip多次输入错误密码

Redislua脚本限制ip多次输入错误密码 不能锁username,因为如果有人恶意保留破解密码的话。会导致用户本人无法登录。 这里我采用 以ip的方式进行锁定。利用redis 设置key:ip。value:当前ip尝试登录的次数 实现逻辑 逻辑简单,假设…...

全球顶级的低代码开发平台,你知道几个?

什么是低代码开发平台? 低码开发平台是一个应用程序,提供图形用户界面编程,从而以非常快的速度开发代码,减少了传统的编程工作。 这些工具有助于快速开发代码,最大限度地减少手工编码的努力。这些平台不仅有助于编码,而且还能快速安装和部署。 低码开发工具的好处 低代码平…...

11-1.Vue2.x基本列表—v-for

文章目录 Vue2.x基本列表—v-for Vue2.x基本列表—v-for <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>基本列表</title><script type"text/javascript" src"../js/vue.j…...

一本书精通推荐算法,轻松搞定入门、面试、进阶

当前互联网高速发展&#xff0c;用户规模和内容规模均迅猛提升。 身处信息严重过载的时代&#xff0c;如何让用户从海量信息中发现自己感兴趣的内容&#xff0c;成了很多公司的核心问题。 在此背景下&#xff0c;搜索系统和推荐系统应运而生。 前者主要解决用户主动寻找内容…...

ADB的基本语法及常用命令

学习网址 ADB命令的基本语法如下&#xff1a; adb [-d|-e|-s <serialNumber>] <command> 如果有多个设备/模拟器连接&#xff0c;则需要为命令指定目标设备。 参数及含义如下&#xff1a; 常用命令如下&#xff1a; 1. 启动ADB服务 adb start-server 2. 停止…...

Linux之bpfjit(2)使用分析和mini-tcpdump实现

Linux之bpfjit(2)使用分析和mini-tcpdump实现 Author: Once Day Date: 2024年4月13日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可以参考专栏&#xff1a;…...

adb常用命令汇总

Android Debug Bridge (adb) 是一个多功能命令行工具&#xff0c;它允许你与连接的Android设备或在电脑上的Android模拟器进行通信。下面列出了一些常用的adb命令&#xff1a; 启动adb服务&#xff1a; adb start-server停止adb服务&#xff1a; adb kill-server查看已连接的设…...

JVM虚拟机(三)垃圾回收简介、垃圾回收算法、分代回收、垃圾回收器种类、G1垃圾回收器

目录 一、什么是垃圾回收&#xff1f;1.1 什么是垃圾回收&#xff1f;1.2 什么对象能被垃圾回收&#xff1f;1&#xff09;引用计数法2&#xff09;可达性分析算法 二、JVM 垃圾回收算法2.1 标记清除算法2.2 标记整理算法&#xff08;标记压缩算法&#xff09;2.3 复制算法2.4 …...

JavaScript基础:js介绍、变量、数据类型以及类型转换

目录 介绍 引入方式 内部方式 外部形式 注释和结束符 单行注释 多行注释 结束符 输入和输出 输出 输入 变量 声明 赋值 关键字 变量名命名规则 常量 数据类型 数值类型 字符串类型 布尔类型 undefined 类型转换 隐式转换 显式转换 Number ✨介绍 &a…...

【牛客SQL快速入门】SQL基础(三)

一、条件函数 IF 条件函数 IF函数是最常用到的条件函数&#xff0c;写法为 if(xn,a,b)&#xff0c;xn代表判断条件&#xff0c;如果xn时&#xff0c;那么结果返回a&#xff0c;否则返回b。 -- 把非北京大学的用户统一归为其他大学 Select device_id,if(university ‘北京大…...

Pytorch手撸Attention

Pytorch手撸Attention 注释写的很详细了&#xff0c;对照着公式比较下更好理解&#xff0c;可以参考一下知乎的文章 注意力机制 import torch import torch.nn as nn import torch.nn.functional as Fclass SelfAttention(nn.Module):def __init__(self, embed_size):super(S…...

PyCharm 2024.1 发布:全面升级,助力高效编程!

PyCharm 2024.1 发布&#xff1a;全面升级&#xff0c;助力高效编程&#xff01; 文章目录 PyCharm 2024.1 发布&#xff1a;全面升级&#xff0c;助力高效编程&#xff01;摘要引言 Hugging Face&#xff1a;模型和数据集的快速文档预览针对 JavaScript 和 TypeScript 的全行代…...

Nginx基础(06)

Nginx基础&#xff08;05&#xff09; uWSGI 介绍 uWSGI 是一个 Web服务器 主要用途是将Web应用程序部署到生产环境中 可以用来连接Nginx服务与Python动态网站 1. 用 uWSGI 部署 Python 网站项目 配置 Nginx 使其可以将动态访问转交给 uWSGI 安装 python 工具及依赖 安…...

【Qt 学习笔记】QWidget的windowOpacity属性 | cursor属性 | font属性

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ QWidget的windowOpacity属性 | cursor属性 | font属性 文章编号&#…...

Python爬虫:requests模块的基本使用

学习目标&#xff1a; 了解 requests模块的介绍掌握 requests的基本使用掌握 response常见的属性掌握 requests.text和content的区别掌握 解决网页的解码问题掌握 requests模块发送带headers的请求掌握 requests模块发送带参数的get请求 1 为什么要重点学习requests模块&…...

C++traits

traits C的标准库提供了<type_traits>,它定义了一些编译时基于模板类的接口用于查询、修改类型的特征&#xff1a;输入的时类型&#xff0c;输出与该类型相关的属性 通过type_traits技术编译器可以回答一系列问题&#xff1a;它是否为数值类型&#xff1f;是否为函数对象…...

gitee和idea集成

1 集成插件 2 配置账号密码 3 直接将项目传到仓库 4直接从gitee下载项目...

阿维·威格德森(Avi Wigderson)研究成果对人工智能领域的应用有哪些影响

AI人工智能的影响 威格德森&#xff08;Avi Wigderson&#xff09;的研究成果对人工智能领域的应用产生了深远的影响。 首先&#xff0c;威格德森在计算复杂性理论、算法和优化方面的贡献为人工智能领域提供了高效、准确的计算模型和算法。他的研究帮助我们更好地理解计算问题…...

【免费领取源码】可直接复用的医院管理系统!

今天给大家分享一套基于SpringbootVue的医院管理系统源码&#xff0c;在实际项目中可以直接复用。(免费提供&#xff0c;文中自取) 系统运行图&#xff08;设计报告和接口文档&#xff09; 1、后台管理页面 2、排班管理页面 3、设计报告包含接口文档 源码免费领取方式 后台私信…...

leetcode代码记录(全排列 II

目录 1. 题目&#xff1a;2. 我的代码&#xff1a;小结&#xff1a; 1. 题目&#xff1a; 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2], [1,2,1], [2,1…...

【数据结构与算法】之双向链表及其实现!

​ 个人主页&#xff1a;秋风起&#xff0c;再归来~ 数据结构与算法 个人格言&#xff1a;悟已往之不谏&#xff0c;知来者犹可追 克心守己&#xff0c;律己则安&#xff01; 目录 1、双向链表的结构及概念 2、双向链表的实现 2.1 要实现的接口…...

记一次奇妙的某个edu渗透测试

前话&#xff1a; 对登录方法的轻视造成一系列的漏洞出现&#xff0c;对接口确实鉴权造成大量的信息泄露。从小程序到web端网址的奇妙的测试就此开始。&#xff08;文章厚码&#xff0c;请见谅&#xff09; 1. 寻找到目标站点的小程序 进入登录发现只需要姓名加学工号就能成功…...

设计模式学习笔记 - 设计模式与范式 -总结:1.回顾23中设计模式的原理、背后的思想、应用场景等

1.创建型设计模式 创建型设计模式包括&#xff1a;单例模式、工厂模式、建造者模式、原型模式。它主要解决对象的创建问题&#xff0c;封装复杂的创建过程&#xff0c;解耦对象的创建代码和使用代码。 1.单例模式 单例模式用来创建全局唯一的对象。一个类只允许创建一个对象…...

22 文件系统

了解了被打开的文件&#xff0c;肯定还有没被打开的文件&#xff0c;就是磁盘上的文件。先从磁盘开始认识 磁盘 概念 内存是掉电易失存储介质&#xff0c;磁盘是永久性存储介质 磁盘的种类有SSD&#xff0c;U盘&#xff0c;flash卡&#xff0c;光盘&#xff0c;磁带。磁盘是…...

OVITO-2.9版本

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…...

【Java开发指南 | 第一篇】类、对象基础概念及Java特征

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 类、对象基础概念Java特征 Java 是一种面向对象的编程语言&#xff0c;它主要通过类和对象来组织和管理代码。 类、对象基础概念 类&#xff1a;类是一个模板&#xff0c;它描述一类对象的行为和状态。例如水…...

Neo4j 图形数据库中有哪些构建块?

Neo4j 图形数据库具有以下构建块 - 节点属性关系标签数据浏览器 节点 节点是 Graph 的基本单位。 它包含具有键值对的属性&#xff0c;如下图所示。 NEmployee 节点 在这里&#xff0c;节点 Name "Employee" &#xff0c;它包含一组属性作为键值对。 属性 属性是…...

电商网站开发技术/百度在线人工客服

Java的枚举类型— 枚举类型相当于特殊的类&#xff0c;经过编译之后同样产生一个class文件。枚举类型中可以定义方法&#xff08;包括构造方法&#xff09;、属性、静态的方法和属性、继承接口、重载覆盖等&#xff0c;类似class。 枚举类型的定义&#xff1a; [public] enum 枚…...

顺德高端网站建设/公司培训

宽为限 紧用功 功夫到 滞塞通 容器生态现状 容器生态&#xff0c;对比2015年之前已经有重大变化&#xff0c;2015-2016年间&#xff0c;互联网、新兴企业都在将其Workload向容器环境迁。容器已不仅仅是两年前的部署工具&#xff0c;更是一种成熟的技术和平台&#xff0c;已经…...

ps如何做网站轮播图/网站免费网站免费优化优化

为什么80%的码农都做不了架构师&#xff1f;>>> 制作一个16*16像素大小的favicon.ico格式图片&#xff0c;放在网站根目录下&#xff0c;在页面head部分插入以下代码 <link rel"icon" type"image/x-icon" href"/interview/favicon.ic…...

私做网站名电子章/如何投放网络广告

一&#xff1a; 思想 有时我们要得到问题的解&#xff0c;先从其中某一种情况进行试探&#xff0c;在试探过程中&#xff0c;一旦发现原来的选择是错误的&#xff0c;那么就退回一步重新选择&#xff0c; 然后继续向前试探&#xff0c;反复这样的过程直到求出问题的解。 二&…...

教育主管部门建设的专题资源网站/百度搜索推广怎么做

Spring中事务控制的一组API事务控制Spring中事务控制&#xff08; Spring中事务控制的API&#xff09;PlateformTransactionManager接口TransationDefinition :事务的定义信息对象TransationStatus:此接口提供的是事务具体的运行状态事务控制 JavaEE 体系进行分层开发&#xf…...

图片上传网站制作/域名注册局

一、概述 二、常见问题&#xff1a; 1、如何为RecyclerView的Item设置点击事件&#xff1f; 1.1 问题描述 类似于下列方法RecyclerView.setOnItemClickListener(OnClickListener) 1.2 解决措施&#xff1a; a、在相应的ViewHolder中添加getItemView() View itemView;//添加成员…...