Java多线程解密:揭秘多线程的奥秘,给你全面了解与实践的权威指南

news2024/11/20 15:16:44

一:进程与线程

概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程。当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是一个线程。

进程:进程是指处于运行过程中的程序,并且具有一定的独立功能。进程是系统进行资源分配和调度的一个单位。当程序进入内存运行时,即为进程。

进程的三个特点:

1:独立性:进程是系统中独立存在的实体,它可以独立拥有资源,每一个进程都有自己独立的地址空间,没有进程本身的运行,用户进程不可以直接访问其他进程的地址空间。

2:动态性:进程和程序的区别在于进程是动态的,进程中有时间的概念,进程具有自己的生命周期和各种不同的状态。

3:并发性:多个进程可以在单个处理器上并发执行,互不影响。

并发性和并行性是不同的概念:并行是指同一时刻,多个命令在多个处理器上同时执行;并发是指在同一时刻,只有一条命令是在处理器上执行的,但多个进程命令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果

线程:线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须拥有一个父进程。线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源。它与父进程的其他线程共享该进程的所有资源。

线程的特点:

  • 线程可以完成一定任务,可以和其它线程共享父进程的共享变量和部分环境,相互协作来完成任务。
  • 线程是独立运行的,其不知道进程中是否还有其他线程存在。
  • 线程的执行是抢占式的,也就是说,当前执行的线程随时可能被挂起,以便运行另一个线程。

一个线程可以创建或撤销另一个线程,一个进程中的多个线程可以并发执行。

二:线程的创建及使用

java使用Thread类代表线程,所有的线程对象都必须是Thread或者其子类的实例,每个线程的作用是完成一定任务,实际上是就是执行一段程序流(一段顺序执行的代码)

方案一:继承Thread类创建线程类

步骤:

1.定义Thread类的子类 并重写该类的Run方法,该run方法的方法体就代表了该线程需要完成的任务

2.创建Thread类的实例,即创建了线程对象

3.调用线程的start方法来启动线程


8618eed4cfbdc0f9f787e22eaebbc0a9.jpeg

主线程方法

aa2970ee127fbe54a36034ce5b9f17b2.jpeg

调用测试方法

方案二:实现Runnable接口

1:定义Runnable接口的实现类,并重写它的Run方法,run方法同样是该线程的执行体!

2:创建Runnable实现类的实例,并将此实例作为Thread的target创建一个Thread对象,该Thread对象才是真正的线程对象!

3:调用start方法启动该线程


a9fd25237fe8a17c8f68edce4bee9e87.jpeg

主线程方法

b5c5189ccf016d3dd66b6c983a1ee4b8.jpeg

调用测试方法

方案三:使用callable和future创建线程

从Java5开始,Java提供 Callable接口,Callable接口提供了一个call()方法可以作为线程执行体,看起来和Runnable很像,但call()方法更强大——call()方法可以有返回值、call()方法可以抛出异常。

Java5提供了Future接口来代表Callable接口的call()方法的返回值,并为Future接口提供了一个FutureTask实现类,该实现类实现类Future接口,也实现了Runnable接口——可以作为Thread的target。

实现步骤:

1:创建Callable接口的实现类,并实现call方法,该call方法会成为线程执行体,且call方法具有返回值,在创建callable接口的实现类!

2:使用FutrueTask类来包装Callable对象,该FutrueTask封装类Callable的call方法的返回值

3:使用FutrueTask对象作为Thread的target创建并启动新线程!

4:使用FutrueTask的get方法获取执行结束后的返回值


13aee9ed2d8f82f2442d15a02e4fb82e.jpeg

主线程方法

caa0d8982a77719f723d8fb409cb4283.jpeg

调用测试方法

三:线程的状态

当线程被创建并被启动时,它既不是一启动就进入了执行状态,在线程的生命周期中,它要经过new(新建),就绪(Runnable),运行(Running),阻塞(Blocked),dead(死亡)。

当线程启动之后,它不可能一直霸占着cpu独自运行,所有cpu需要在多条线程轮流切换,于是线程就也会多次在运行.就绪之间切换

新建和就绪状态

--新建状态:

当程序使用new关键字创建了一个线程时,该线程就处于新建状态。

此时的它和其它java对象一样,仅有虚拟机分配内存,并初始化成员变量的值。此时的线程对象并没有表现出线程的任何动态特征,程序也不会执行线程的线程执行体

--就绪状态:

当线程对象调用了start()方法后,该线程就处于就绪状态,java虚拟机会为其创建方法调用栈和程序计数器,处于该状态的线程并没有开始执行,只是表明该线程可以运行了,至于该线程何时运行,取决于JVM的调度。

注意!!!

启动线程要调用start方法,而不是run方法,永远不要调用线程的run方法,如果调用run方法,系统会把线程对象当作普通的对象,会吧线程的执行体当作普通方法来调用!在调用了run方法之后,该线程就不在处于新建状态,不要再调用该线程的start方法!java中只能对处于新建状态的线程使用start方法,否则将会引发IllegalThreadStateException异常!

运行状态和阻塞状态

当发生如下的几种情况时,将会进入阻塞状态:

当线程调用sleep方法主动放弃所占用的处理器资源

线程调用了一个阻塞时的IO方法,在该方法返回之前,线程会被阻塞

线程试图获得一个同步监视器,但该同步监视器正被其他线程锁持有

线程正在等待某个通知(notify)

程序调用了线程的suspend方法将该线程挂起

当以上几个情况,当发生如下的情况将会重新进入就绪状态

调用sleep()方法过了指定时间

线程调用的阻塞时IO方法依旧返回

线程成功地获得了试图获得的同步监视器

现在正在等待某个通知,而其它线程发出一个通知

处于挂起状态的线程被调用了resume()方法

注意!!!

线程从阻塞状态只能进入就绪状态,无法直接进入运行状态。就绪和运行状态之间的转换通常不受程序控制,而是系统线程的调度决定的。

调用yield()方法可以让处于运行时的线程转入就绪状态。

3:线程死亡

线程会以以下三种方式结束,结束后处于死亡状态

  1. run或call方法执行完成,程序结束
  2. 线程抛出一个未捕获的Exception或者Error
  3. 直接调用该线程的stop方法来结束线程

当主线程结束时,其它线程不受任何影响,并不会随之结束。一旦子线程启动起来后,他就会拥有和主线程相同的地位,它不会受主线程影响。

为了测试某个线程是否死亡,可以调用该线程的isAlive方法,当线程处于就绪,运行,阻塞三种状态时,将返回true;当线程处于新建,死亡两种状态时返回为false。

不要试图对一个已经死亡的线程调用start方法让它重新启动,死亡后的线程无法作为线程使用。

如果处于非新建状态的线程使用start方法,就会引发IllegalThreadStateException异常。

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

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

相关文章

Python学习基础笔记七十二——IDE集成开发环境

集成开发环境,英文缩写是IDE。 IDE可以帮你更高效地开发项目代码。因为它提供了非常实用的功能,比如项目文件管理、语法高亮、代码导航、自动补齐代码、语法静态检查、调试、版本控制等等。 两款IDE:Pycharm和VSCode。 pycharm中的代码文件都…

香港学界呼吁RWA“在港先发”,构建基于港元稳定币的Web3生态!

2023年以来,市场对于RWA(Real World Assets)即真实世界资产“代币化”的讨论愈发频繁,一些观点认为 RWA将在下一轮加密资产牛市中成为焦点,部分Web3创业者和传统金融企业也快速将业务方向瞄准相关赛道,而被…

Java|学习|异常

1.异常 1.1 异常 1.1.1 概述 异常:就是程序出现了不正常的情况。 Error:严重问题,不需要处理。 Exception:称为异常类,它表示程序本身可以处理的问题。 RuntimeException:在编译器不检查,出…

WorkPlus即时通讯办公软件,助力企业实现移动化办公

在移动互联网的时代背景下,企业对于高效的移动平台需求日益迫切。WorkPlus作为领先品牌,致力于为企业打造卓越的移动平台,助力企业实现协作与效率的突破。本文将探讨WorkPlus如何通过其专业的解决方案,为企业打造无限可能的移动办…

高级系统架构设计师_笔记_真题

2020 科目一 位示图的计算 分页管理-页式存储 软件系统的文档可以分为用户文档和系统文档两类。软件活动: 对应软件开发的各种活动,软件开发工具包括:需求分析工具、设计工具、编码和排错工具、测试工具等。按需求描述定义的方法可将需求分…

day35

今日内容概要 Socket抽象层(socket编程) 基于TCP协议的借助socket可以编程客户端和服务端的程序 链接循环 通信循环 基于UDP协议的套接字(socket)编程 粘包现象 如何解决粘包现象(重要的是解决的思路) struct模块的使用(打包、解包) 今日内容详细 Socket抽象层&#x…

论文阅读:Rethinking Range View Representation for LiDAR Segmentation

来源ICCV2023 0、摘要 LiDAR分割对于自动驾驶感知至关重要。最近的趋势有利于基于点或体素的方法,因为它们通常产生比传统的距离视图表示更好的性能。在这项工作中,我们揭示了建立强大的距离视图模型的几个关键因素。我们观察到,“多对一”…

Linux:mongodb数据库基础操作(3.4版本)

安装 3.*版本和4.*版本安装都是一样的 Linux:mongodb数据库源码包安装(4.4.25版本)_鲍海超-GNUBHCkalitarro的博客-CSDN博客https://blog.csdn.net/w14768855/article/details/133826626?spm1001.2014.3001.5501 mysql和mongodb对比 登录…

【SpringCloud-10】SCA-nacos

前言: 前面介绍的springcloud,可以看做第一代,称为:SCN(spring cloud Netflix); 接下来介绍的是第二代:SCA(spring cloud alibaba); SCA主要有以下组件&#…

【Java 进阶篇】创建 JavaScript 轮播图:让网页焕发生机

欢迎大家来到本篇博客,今天我们将一起探讨如何使用 JavaScript 创建一个精美的轮播图。轮播图是现代网站设计的关键元素之一,它能够使网页更加吸引人,提高用户体验。无需担心,本文将面向基础小白,从头开始解释每一步。…

“最强7B模型”论文发布,揭秘如何超越13B版Llama 2

来自“欧洲OpenAI”的“最强7B开源模型”Mistral最近可谓是圈粉无数。 它各方面的测试指标全面超越了13B的Llama2,甚至让一众网友觉得羊驼不香了。 最新消息是,Mistral AI团队已经发布了相关论文,透露背后的技术细节。 Mistral不仅全面战胜…

多个子div在父中垂直居中

在一个div下&#xff0c;有多个子div&#xff0c;且子div都是水平垂直居中 <template><div><div class"far"><!-- 注意需要多包裹一层 --><div><div class"son1">1</div><div class"son2">222…

30天工作量,推荐4个ai写作生成器工具,一键搞定!

全新升级&#xff01;畅销热门AI写作工具盘点40强&#xff0c;助你一键呈现顶尖文案&#xff01; AI写作工具&#xff0c;引领时代潮流&#xff0c;让办公生活更高效&#xff01;小编特意整理了市面上最好用的AI写作工具&#xff0c;共计40款&#xff01;你使用过哪些&#xff…

Centos中如何删除带有特殊符号的乱码文件_rz命令产生的乱码文件如何删除_使用文件号删除乱码文件---Linux运维工作笔记058

在使用rz命令进行文件上传的时候,偶尔会产生一堆的乱码文件,比如: 可以看到有一堆的乱码文件. 普通的乱码文件,直接rm -rf 文件名就可以删除了,但是有一些不行,包含特殊符号的,比如: 这个文件报错了,可以看到用rm -rf 根本删除不掉. 这个文件后面包含了一个.对吧 那该怎么解决…

C++前缀和算法应用:矩形区域不超过 K 的最大数值和

基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 题目 给你一个 m x n 的矩阵 matrix 和一个整数 k &#xff0c;找出并返回矩阵内部矩形区域的不超过 k 的最大数值和。 题目数据保证总会存在一个数值和不超过 k 的矩形区域。 示例 1&#x…

消息队列(中间件)

通信协议&#xff1a; 为了实现客户端和服务器之间的通信来完成的逻辑&#xff0c;基于TCP实现的自定义应用层协议。通过这个协议,完成客户端–服务器远程方法调用。 序列化/反序列化&#xff1a; 通过网络传输对象把对象存储到硬盘上。 序列化&#xff1a;把对象转化为二进制的…

windwos文件句柄数限制

1、修改注册表&#xff0c;位置如下&#xff1a; HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Windows​ 2、设置 1、GDIProcessHandleQuota 此项设置GDI句柄数量&#xff0c;默认值为2710(16进制)/10000(10进制)&#xff0c;该值的允许范围为 256 ~ 16…

pip快速安装torch、opencv、scipy库

目录 一、pip安装torch 1.1 torch介绍 1.2 torch.nn相关库的导入 1.3win10上torch的安装命令 二、pip安装Opencv 三、pip安装scipy库 一、pip安装torch 1.1 torch介绍 torch的基本功能&#xff1a; ①torch&#xff1a;张量的相关运算&#xff0c;例如&#xff1a;创…

微信小程序------框架

目录 视图层 WXML 数据绑定 列表渲染 条件渲染 模板 wsx事件 逻辑层 生命周期 跳转 视图层 WXML WXML&#xff08;WeiXin Markup Language&#xff09;是框架设计的一套标签语言&#xff0c;结合基础组件、事件系统&#xff0c;可以构建出页面的结构。 先在我们的项目中…

GitLab(1)——GitLab安装

目录 一、使用设备 二、使用rpm包安装 Gitlab国内清华源下载地址&#xff1a; ①下载命令如下&#xff1a; ②安装命令如下&#xff1a; ③删除rpm包 ④配置 ⑤重载 ⑥重启 ⑦配置自启动 ⑧打开8989端口并重启防火墙 三、GitLab登录 ①访问GitLab的URL ②输入用户…