第1章 多线程基础
第1章 多线程基础
1.1.2 线程与进程的关系
进程可以看成是线程的容器,而线程又可以看成是进程中的执行路径。
1.2 多线程启动
线程有两种启动方式:实现Runnable接口;继承Thread类并重写run()方法。
执行进程中的任务时才会产生线程,因此需要一种描述任务的方式,这可以由Runnable接口来提供。要想定义任务,需要实现Runnable接口并且重写run()方法,然后再将Runnable的实现对象作为参数传递给Thread类。
调用Thread类的start()方法,启动线程,向CPU发出请求,去执行任务。
还可以采用继承Thread类并且重写run()方法,然后调用start()启动线程。
通常情况下,实现Runnable接口然后启动线程是一个更好的选择,这可以提高程序的灵活性和扩展性,并且用Runnable接口描述任务也更容易理解。
1.2.1 线程标识
Thread类用于管理线程,如设置线程优先级、设置Daemon属性、读取线程名字和ID、启动线程任务、暂停线程任务、中断线程等。
为了管理线程,每个线程在启动后都会生成一个唯一的标识符,并且在其生命周期内保持不变。当线程被终止时,该线程ID可以被重用。而线程的名字更加直观,但是不具有唯一性。
1.2.2 Thread与Runnable
Runnable接口表示线程要执行的任务。当Runnable中的run()方法执行时,表示线程在激活状态,run()方法一旦执行完毕,即表示任务完成,则线程将被停止。
Thread类默认实现了Runnable接口,并且其构造方法的重载形式允许传入Runnable接口对象作为任务。
通过Thread类的源代码可以发现,线程的两种启动方式,其本质都是实现Thread类中的run()方法。而实现Runnable接口,然后传递给Thread类的方式,比Thread子类重写run()方法更加灵活。
1.2.3 run()与start()
调用Thread对象的start()方法,使线程对象开始执行任务,这会触发Java虚拟机调用当前线程对象的run()方法。调用start()方法后,将导致两个线程并发运行,一个是调用start()方法的当前线程,另外一个是执行run()方法的线程。
如果重复调用start()方法,这是一个非法操作,它不会产生更多的线程,反而会导致IllegalThreadStateException异常。
1.2.4 Thread源码分析
创建Thread类实例,首先会执行registerNatives()方法,它在静态代码块中加载。线程的启动、运行、生命期管理和调度等都高度依赖于操作系统,Java本身并不具备与底层操作系统交互的能力。因此线程的底层操作都使用了native方法,registerNatives()就是用C语言编写的底层线程注册方法。
无论通过Thread类的哪种构造方法去创建线程,都需要首先调用init()方法,初始化线程环境
在init()方法中,做了如下操作:
(1)设置线程名称。
(2)将新线程的父线程设置为当前线程。
(3)获取系统的安全管理SecurityManager,并获得线程组。SecurityManager在Java中被用来检查应用程序是否能访问一些受限资源,如文件、套接字(socket)等。它可以用在那些具有高安全性要求的应用程序中。
(4)获取线程组的权限检查。
(5)在线程组中增加未启动的线程数量。
(6)设置新线程的属性,包括守护线程属性(默认继承父线程)、优先级(默认继承父线程)、堆栈大小(如果为0,则默认由JVM分配)、线程组、线程安全控制上下文(一种Java安全模式,设置访问控制权限)等。
1.3 线程状态
Java中的线程存在6种状态,分别是NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。我们可以通过Thread类中的Thread.getState()方法获取线程在某个时期的线程状态。在给定的时间点,线程只能处于一种状态。
1.3.1 NEW状态
NEW代表着线程新建状态,一个已创建但是未起动(start)的线程处于NEW状态。
1.3.2 RUNNABLE状态
RUNNABLE状态表示一个线程正在Java虚拟机中运行,但是这个线程是否获得了处理器分配资源并不确定。调用Thread的start()方法后,线程从NEW状态切换到了RUNNABLE状态。
1.3.3 BLOCKED状态
BLOCKED为阻塞状态,表示当前线程正在阻塞等待获得监视器锁。当一个线程要访问被其他线程synchronized锁定的资源时,当前线程需要阻塞等待。
1.3.4 WAITING状态
WAITING表示线程处于等待状态。
在当前线程中调用如下方法之一时,会使当前线程进入等待状态:
Object类的wait()方法(没有超时设置);
Thread类的join()方法(没有超时设置);
LockSupport类的park()方法。
处于等待状态的线程,正在等待另外一个线程去完成某个特殊操作。例如,在某个线程中调用了Object对象的wait()方法,它会进入等待状态,等待Object对象调用notify()或notifyAll()方法。一个线程对象调用了join()方法,则会等待指定的线程终止任务。
1.3.5 TIMED_WAITING状态
TIMED_WAITING表示线程处于定时等待状态。
在当前线程中调用如下方法之一时,使当前线程进入定时等待状态:
Object类的wait()方法(有超时设置);
Thread类的join()方法(有超时设置);
Thread类的sleep()方法(有超时设置);
LockSupport类的parkNanos ()方法;
LockSupport类的parkUntil()方法。
1.3.6 WAITING与BLOCKED的区别
WAITING、TIMED_WAITING、BLOCKED这几个线程状态,都会使当前线程处于停顿状态,因此容易混淆。下面简单总结一下这些状态之间的区别:
(1)Thread.sleep()不会释放占有的对象锁,因此会持续占用CPU。
(2)Object.wait()会释放占有的对象锁,不会占用CPU。
(3)BLOCKED使当前线程进入阻塞后,为了抢占对象监视器锁,一般操作系统都会给这个线程持续的CPU使用权。
(4)LockSupport.park()底层调用UNSAFE.park()方法实现,它没有使用对象监视器锁,不会占用CPU。
1.3.7 TERMINATED状态
TERMINATED表示线程为完结状态。当线程完成其run()方法中的任务,或者因为某些未知的异常而强制中断时,线程状态变为TERMINATED。
1.3.8 线程状态转换
前面我们学习了Java线程的6种状态,接下来通过图1-2对线程状态转换进行汇总。在图1-2中,把线程RUNNABLE状态细分为两种:runnable(准备就绪)和running(运行中)。runnable表示线程刚刚被JVM启动,还没有获得CPU的使用权;running表示线程获得了CPU的使用权,正在运行。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M6gT7bvG-1678243017014)(null)]
1.4 sleep()与yield()
1.4.1 线程休眠sleep()
Thread类的sleep()方法,使当前正在执行的线程以指定的毫秒数暂时停止执行,具体停止时间取决于系统定时器和调度程序的精度和准确性。当前线程状态由RUNNABLE切换到TIMED_WAITING。调用sleep()方法不会使线程丢失任何监视器所有权,因此当前线程仍然占用CPU分片。
调用sleep()方法可能会抛出InterruptedException异常,它应该在run()方法中被捕获,因为异常无法传递到其他线程,如主线程就无法捕获子线程抛出的异常。
Java SE5引入了更加显式的sleep()版本,作为TimeUit类的一部分。例如,TimeUnit.MILLISECONDS.sleep(1000)等价于Thread.sleep(1000),表示休眠1秒。TimeUnit类提供了更好的可读性。
1.4.2 线程让步yield()
Thread类的yield()方法对线程调度器发出一个暗示,即当前线程愿意让出正在使用的处理器。调度程序可以响应暗示请求,也可以自由地忽略这个提示。如图1-2所示,线程调用yield()方法后,可能从running状态转为runnable状态。
需要强调的是:**yield()仅仅是一个暗示,没有任何机制保证它一定会被采纳。**线程调度器是Java线程机制的底层对象,可以把CPU的使用权从一个线程转移到另外一个线程。如果你的计算机是多核处理器,那么分配线程到不同的处理器执行任务要依赖线程调度器。
1.5 线程优先级
每个线程都有优先级。具有较高优先级的线程可能优先获得CPU的使用权。创建一个新的Thread对象时,新线程的优先级默认与创建线程的优先级一致。
JDK中实际上存在着10个优先级,但是这与大多数操作系统不能建立很好的映射关系。比如Windows有7个线程优先级设置,而Sun的Solaris只有两个线程优先级,因此在Java中一般只使用下面的三种优先级设置。
不应该过分依赖于线程优先级的设置,理论上线程优先级高的会优先执行,但实际情况可能并不明确。例如,线程调度机制还没有来得及介入时,线程可能就已经执行完了。所以优先级具有一定的“随机性”。
1.5.1 线程优先级与资源竞争
具有较高优先级的线程会优先得到调度系统资源分配。也就是说优先级高的线程可以优先竞争共享资源。但线程的优先级调度和底层操作系统有密切的关系,在各个平台上表现不一并且无法精准控制。因此在要求严格的场合,需要开发者在应用层解决线程调度问题。
当调用Thread.yield()方法时,会给线程调度器一个暗示,即优先级高的其他线程或相同优先级的其他线程,都可以优先获得CPU分片。
1.6 守护线程
1.6.1 守护线程的概念
在Java线程中有两种线程,一种是用户线程,另一种是守护线程(Daemon)。
所谓守护线程,是指在程序运行的时候在后台提供一种通用服务的线程。比如,垃圾回收线程就是一个很称职的守护者(当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用)。
Daemon线程与用户线程在使用时没有任何区别,唯一的不同是:当所有用户线程结束时,程序也会终止,Java虚拟机不管是否存在守护线程,都会退出。
调用Thread对象的setDaemon()方法,可以把用户线程标记为守护者。调用isDaemon()方法可以判断线程是否是一个守护线程。
空间,以便空间被后来的新对象使用)。
Daemon线程与用户线程在使用时没有任何区别,唯一的不同是:当所有用户线程结束时,程序也会终止,Java虚拟机不管是否存在守护线程,都会退出。
调用Thread对象的setDaemon()方法,可以把用户线程标记为守护者。调用isDaemon()方法可以判断线程是否是一个守护线程。
相关文章:
第1章 多线程基础
第1章 多线程基础 1.1.2 线程与进程的关系 进程可以看成是线程的容器,而线程又可以看成是进程中的执行路径。 1.2 多线程启动 线程有两种启动方式:实现Runnable接口;继承Thread类并重写run()方法。 执行进程中的任务时才会产生线程&a…...
Linux基本指令(一)
文章目录文件操作文档操作系统管理网络通信备份压缩Ctrl Alt T 打开终端 文件操作 1.复制文件 cp afile bfile (将名为afile的文件复制到名为bfile的文件夹中,如果bfile文件不存在,系统将会创建此文件,如果bfile文件已经存在&a…...
el-dialog子组件在mounted周期内获取不到dom?
el-dialog子组件在mounted周期内获取不到dom?一、问题描述二、分析原因三、猜测正常父子组件在mounted生命周期内可以获得dom 父created—子created—子mounted—父mounted----子updated—父updated 一、问题描述 ** el-dialog控制显示隐藏是css控制的display&…...
第九章 opengl之光照(光照贴图)
OpenGL光照贴图漫反射贴图镜面光贴图光照贴图 一个物体的不同部分是不同的材质,那么会有不同的环境光和漫反射颜色表现。 漫反射贴图 原理就是:纹理。 是对同样的原理使用了不同的名字:其实都是使用一张覆盖物体的图像,让我们能…...
JDK动态代理(powernode CD2207 video)(内含教学视频+源代码)
JDK动态代理(powernode CD2207 video)(内含教学视频源代码) 教学视频原代码下载链接地址:https://download.csdn.net/download/weixin_46411355/87545977 目录JDK动态代理(powernode CD2207 video…...
【Linux】Sudo的隐晦bug引发的一次业务问题排查
Sudo的隐晦bug引发的一次业务问题排查写在前面问题描述问题排查高负载现象排查日志排查跟踪任务调度过程Sudo引发的问题手动复现问题分析处理方案写在前面 记录一次生产环境sudo启动进程频繁被Kill且不报错的异常处理过程,如果遇到同样的问题只想要解决方案&#x…...
Java VisualVM 安装 Visual GC 插件图文教程
文章目录1. 通过运行打开 Java VisualVM 监控工具2. 菜单栏初始视图说明3. 工具插件菜单说明4. 手工安装插件5. 重启监控工具查看 Visual GC1. 通过运行打开 Java VisualVM 监控工具 首先确保已安装 Java 环境,如此处安装版本 JDK 1.8.0_161 C:\Users\niaonao>j…...
【C语言】详解静态变量static
关键字static 在C语言中:static是用来修饰变量和函数的static主要作用为:1. 修饰局部变量-静态局部变量 2. 修饰全局变量-静态全局变量3. 修饰函数-静态函数在讲解静态变量之前,我们应该了解静态变量和其他变量的区别: 修饰局部变量 //代码1 #include &l…...
SpringBoot整合ElasticSearch实现模糊查询,排序,分页,高亮
目录 前言 1.框架集成-SpringData-整体介绍 1.1Spring Data Elasticsearch 介绍 2.框架集成Spring Data Elasticsearch 2.1版本说明 2.2.idea创建一个springboot项目 2.3.导入依懒 2.3.增加配置文件 2.4Spring Boot 主程序。 2.5.数据实体类 2.6.配置类 2.7.DAO 数据…...
YARN基本架构
主要由ResourceManager、NodeManager、ApplicationMaster和Container等组件构成,如图所YA示。 ResourceManager(RM) RM是全局资源管理器,负责整个系统的资源管理和分配 主要由两个组件构成:Scheduler调度器和应用程序…...
【C++复习】类和对象全知识点总结
类和对象写在前面类和对象面向对象类类的定义类的访问限定符类的作用域类的实例化类对象大小this指针类的默认成员函数构造函数析构函数拷贝构造函数运算符重载赋值运算符重载前置后置重载取地址及const取地址操作符重载const 成员static 成员友元友元函数有元类内部类匿名对象…...
基于轻量级YOLOv5开发构建汉字检测识别分析系统
汉字检测、字母检测、手写数字检测、藏文检测、甲骨文检测在我之前的文章中都有做过了,今天主要是因为实际项目的需要,之前的汉字检测模型较为古老了还使用的yolov3时期的模型,检测精度和推理速度都有不小的滞后了,这里要基于yolo…...
leetcode-每日一题-66(简单题,数组)
这道题其实还没那么简单,中间还是有的绕的。。。。给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会…...
LeetCode295之数据流的中位数(相关话题:优先队列)
题目描述 中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: MedianFinder() 初始化 Media…...
助你加速开发效率!告别IDEA卡顿困扰的性能优化技巧
在现代软件开发中,IDE(集成开发环境)是一个必不可少的工具。IntelliJ IDEA是一个广受欢迎的IDE,但有时候IDE的性能可能会受到影响,导致开发人员的工作效率降低。本文将介绍一些可以提高IDE性能的技巧,帮助开…...
Java设计模式-适配器模式
1、简介 适配器模式是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。 2、适配器模式分类 目标接口(Target&#x…...
Linux 练习六 (IPC 管道)
文章目录1 标准管道流2 无名管道(PIPE)3 命名管道(FIFO)3.1 创建删除管道文件3.2 打开和关闭FIFO文件3.3 管道案例:基于管道的客服端服务器程序使用环境:Ubuntu18.04 使用工具:VMWare workstati…...
合并两个有序链表(精美图示详解哦)
全文目录引言合并两个有序链表题目描述方法一:将第二个链表合并到第一个思路实现方法二:尾插到哨兵位的头节点思路实现总结引言 在前面两篇文章中,我们介绍了几道链表的习题:反转链表、链表的中间结点、链表的倒数第k个结点&…...
33 JSON操作
目录 一、介绍 二、JSON的特点 三、JSON语法 1、json中的数据类型 四、JSON文件的定义 五、读取JSON文件 1、读取json文件的两种方式 (1)read、write (2)json.load 2、使用json.load读取json文件的步骤 3、练习读取json文件 六、练…...
三八妇女节快乐----IT女神活动随笔
献丑了,一首小小散文诗,请大家轻喷 O(≧口≦)O 我的答案 天下芸芸众生,好似夜幕漫天繁星。 与你相识,只是偶然。 简单的一个招呼,于是开始了一段故事。 我们或是诉说,或是分享; 我们彼此倾听&…...
【PSO-PID】使用粒子群算法整定PID参数控制起动机入口压力值
最近在学优化算法,接触到了经典寻优算法之粒子群PSO,然后就想使用PSO算法来调节PID参数,在试验成功之后将此控制算法应用到了空气起动系统上,同时与之前的控制器进行对比看看哪种控制效果最好。 0 引言 PID参数整定主要有两种&…...
当代数据分析指南:激发商业洞见的七个方法(上)
如果说眼下的发生的事能证明什么,那就是基于实时可信的数据分析正在变得越来越重要。但是要是想要在需要的时候准确地获取中肯的洞察,我们所需要的可不只是漂亮的可视化。 如何让你的员工都有能力和机会都做出最好的决策,不管这个决策会有多…...
javaWeb核心02-JSP、EL、JSTL、MVC
文章目录JSP1,JSP 概述2,JSP 快速入门2.1 搭建环境2.2 导入 JSP 依赖2.3 创建 jsp 页面2.4 编写代码2.5 测试3,JSP 原理4,JSP 脚本4.1 JSP 脚本分类4.2 案例4.2.1 需求4.2.2 实现4.2.3 成品代码4.2.4 测试4.3 JSP 缺点5࿰…...
spring-boot+mybatis-plus连接Oracle数据库,及查询相关数据
配置java 略(这里我用的是jdk1.8) 配置maven 环境变量: M2_HOME:D:\LJ\software\java\maven\apache-maven-3.6.3 Path:%M2_HOME%\bin 仓库/jdk/镜像云设置(./config/sitting) 仓库 <localRepository> D:/…...
电商使用CRM系统有什么好处,如何选择
数据显示,使用电商CRM客户管理系统后,企业销售额提高了87%,客户满意度提高了74%,业务效率提高了73%。要在竞争激烈的电商市场取得成功,与目标受众的有效沟通是有效的方法。下面说说什么是电商CRM系统?电商C…...
Nacos2.2.0多数据源适配oracle12C-修改Nacos源码
从2.2.0版本开始,可通过SPI机制注入多数据源实现插件,并在引入对应数据源实现后,便可在Nacos启动时通过读取application.properties配置文件中spring.datasource.platform配置项选择加载对应多数据源插件.本文档详细介绍一个多数据源插件如何实现以及如何使其生效。 文章目录一…...
第十四届蓝桥杯三月真题刷题训练——第 5 天
目录 题目1:数的分解 题目描述 运行限制 代码: 题目2:猜生日 题目描述 运行限制 代码: 题目3:成绩分析 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码: 题目4:最大和…...
大数据框架之Hive:第3章 DDL(Data Definition Language)数据定义
第3章 DDL(Data Definition Language)数据定义 3.1 数据库(database) 3.1.1 创建数据库 1)语法 CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPER…...
概率论小课堂:统计学是大数据方法的基础
文章目录 引言I 统计学1.1 统计学的内容1.2 统计学的目的II 用好数据的五个步骤2.1 设立研究目标2.2 设计实验,选取数据。2.3 根据实验方案进行统计和实验,分析方差。2.4 通过分析进一步了解数据,提出新假说。2.5 使用研究结果III 数据没用好的原因3.1 霍桑效应3.2 数据的稀…...
监控集群概念讲解
监控概述 1、监控的重要性 监控是运维日常的重要工作之一; 监控是有多重要? 监控可以帮助运维监控服务器的状态;要及时解决; 如果淘宝、腾讯宕机了1个小时? 损失是无法估量的; 服务器是否故障、宕不…...
嘉兴网站建设/世界足球世界排名
创建数组对象: 通过NumPy库的array函数可以创建ndarray数组。通常来说,ndarray是一个通用的数据容器,即其中的所有元素都需要相同的类型。NumPy库能将数据(列表,元组,数组或者其他序列类型)转换…...
小企业来说 电子商务网站服务器的建设方案/百度网
Android 进程间通信 一、 本地服务与远程服务(AIDL服务)区别本地服务:无法供在设备上运行的其他应用程序访问。一般而言, 这些服务类型仅支持承载该服务的应用程序。onBind方法为在同一设备上运行的外部应用程序提供一个接口来与服务通信。 1.1不需和A…...
公众号自己做电影网站吗/常见的营销方式有哪些
2019独角兽企业重金招聘Python工程师标准>>> DefaultBeanDefinitionDocumentReader.processBeanDefinition() 完成 Bean 标签解析的核心工作: 解析工作分为三步: 解析默认标签;解析默认标签后下得自定义标签;注册解析后…...
专业网页制作网站推广公司/软文怎么写吸引人
解决WAMP搭建PHP环境后后局域网其他机器无法访问的方法:首先确定关闭了防火墙并且80端口没有被占用;然后修改apache的【httpd.conf】文件;最后重启apache即可。【相关学习推荐:php图文教程】解决WAMP搭建PHP环境后后局域网其他机器…...
vi设计作品/seo常见优化技术
http://www.hankcs.com/nlp/ner/place-names-to-identify-actual-hmm-viterbi-role-labeling.html 命名实体识别(Named Entity Recognition)也是自然语言处理中的一个难关,特别是中文这样没有大小写等固定形态的语言。上次介绍过《实战HMM-Vi…...