《Java面向对象程序设计》学习笔记——第 15 章 Java 多线程机制

​笔记汇总:《Java面向对象程序设计》学习笔记

​# 第 15 章 Java 多线程机制

Java 语言的一大特点就是内置了对多线程的支持。

多线程是指同时存在几个执行体,按几条不同的执行线索共同工作的情况。

我们感觉线程正在同步执行,但并不是真的同时执行多个线程,只是Java 快速地从一个线程切换到另一个线程。

Java 虚拟机( JVM )负责管理线程。

15.1 Java 中的线程

15.1.1 程序、进程与线程

程序

  • 程序是一段静态的代码。

进程

  • 进程是程序的一次动态执行过程。

  • os 可以管理多个进程,即让多个进程都机会使用系统的资源,比如 CPU 资源。

    (一个 OS 里可以多个进程)

线程

  • 一个进程在其执行过程中可以产生多个线程。
  • 有自己独特的运行机制。
  • 线程是比进程更小的执行单位,也有产生、存在和消亡的过程。

其他

  • 每个进程都有一段专用的内存区域,但,线程间可以共享相同的内存单元(包括代码与数据)
  • 操作系统分时管理各个进程,按时间片轮流执行每个进程。
  • Java 的多线程就是在操作系统每次分时给 Java 程序一个时间片的 CPU 时间内,在若干个独立的可控制的线程之间进行切换
  • 每个 Java 程序都有一个默认的主线程。

15.1.2 线程的状态与生命周期

Java 语言使用 Thread 类及其子类的对象来表示线程。

使用 Thread 类及其子类的对象来表示线程。

Thread 提供 getstate() 方法返回枚举类型 Thread.State 的下列枚举常量之一:

NEW , RUNNABLE , BLOCKED , WAITING , TIMED_WAITING , TERMINATED

新建状态( NEW )

  • 当一个 Thread 类或其子类的对象被声明并创建时,新生的线程对象处于NEW状态,称作新建状态。

  • 即尚未启动(没有调用 start() 方法)的线程处于此状态。

可运行状态 (RUNNABLE)

  • 处于 NEW 状态的线程,调用 Thread 类提供的 start() 方法,进入 RUNNABLE状态。

  • NEW 状态线程调用 start() ,让自己进入 RUNNABLE状态。

  • JVM 就会知道又有一个新一个线程排队等候切换了。

  • 当 JVM 将 CPU 使用权切换给 RUNNABLE 状态的线程时,如果线程是 Thread 的子类创建的,该类中的 run() 方法就立刻执行。

    如果线程是 Thread 的子类创建的,该类中的 run () 方法就立刻执行。所以我们必须在子类中重写父类的 run() 方法。

中断状态 (BLOCKED 、 WAITING 、 TIMED_WAITING)阻塞、等待、有限时间等待

  • BLOCKED 、 WAITING 、 TIMED_WAITING 状态都属于中断状态。
  • 当中断的线程重新进入 RUNNABLE 状态后,一旦 JVM 将 CPU 使用权切换给该线程, run() 方法将从中断处继续执行。

死亡状态 (TERMINATED)终止

  • 线程完成了它的全部工作,即执行完 run() 方法,该线程进入 TERMINATED 状态。

  • 只有处于NEW状态的线程可以调用 start() 方法,处于其他状态的线程都不可以调用 start() 方法,否则将触发 ILLegalThreadStateException 异常。

在主线程中用 Thread 的子类创建了两个线程,这两个线程在命令行窗口分别输出 5 句“老虎”和“小猫”;主线程在命令行窗口输出 6 句“主人”。

注意,程序在不同的计算机上运行或在同一台计算机上反复运行的结果不尽相同。

public class Tiger extends Thread {public void run() {for (int i = 1; i <= 5; i++) {System.out.print("|老虎" + i);try {sleep(1000); // 状态:TIMED_WAITING} catch (Exception exp) {}}}
}public class Cat extends Thread {public void run() {for (int i = 1; i <= 5; i++) {// System.out.print("|小猫"+i+"状态:"+getState()+"|");System.out.print("|小猫" + i);}}
}public class Example15_1 { public static void main(String args[]) { // 主线程Tiger tiger;Cat cat;tiger = new Tiger(); // 创建线程cat = new Cat(); // 创建线程System.out.println("tiger的状态:" + tiger.getState());System.out.println("cat状态:" + cat.getState());tiger.start(); // 启动线程cat.start(); // 启动线程for (int i = 1; i <= 6; i++) {System.out.printf("\n%s", "tiger状态:" + tiger.getState());System.out.printf("\n%s", "cat状态:" + cat.getState());System.out.printf("\n%s", "主人" + i);}System.out.printf("\n%s", "|tiger的状态:" + tiger.getState());System.out.printf("\n%s", "|cat状态:" + cat.getState());}
}

输出(不唯一,每次线程顺序都可能不一样)

tiger的状态:NEW
cat状态:NEWtiger状态:RUNNABLE|小猫1|老虎1|小猫2
cat状态:BLOCKED|小猫3
主人1|小猫4
tiger状态:TIMED_WAITING|小猫5
cat状态:RUNNABLE
主人2
tiger状态:TIMED_WAITING
cat状态:TERMINATED
主人3
tiger状态:TIMED_WAITING
cat状态:TERMINATED
主人4
tiger状态:TIMED_WAITING
cat状态:TERMINATED
主人5
tiger状态:TIMED_WAITING
cat状态:TERMINATED
主人6
|tiger的状态:TIMED_WAITING
|cat状态:TERMINATED|老虎2|老虎3|老虎4|老虎5

15.1.3 线程的调度与优先级

处于就绪状态的线程首先进人就绪队列排队等候 CPU 资源,同一时刻在就绪队列中的线程可能有多个。

Java 虚拟机中的线程调度器负责管理线程。

在采用时间片的系统中,每个线程都有机会获得 CPU 的使用权,以便使用 CPU 资源执行线程中的操作。

当线程使用 CPU 资源的时间到了后,即使线程没有完成自己的全部操作, Java 调度器也会中断当前线程的执行,把 CPU 的使用权切换给下一个排队等待的线程,当前线程将等待 CPU 资源的下一次轮回,然后从中断处继续执行。

Java 调度器的任务是使高优先级的线程能始终运行,一旦时间片有空闲,则使具有同等优先级的线程以轮流的方式顺序使用时间片。

在实际编程时,不提倡使用线程的优先级来保证算法的正确执行。

15.2 用 Thread 的子类创建线程

用 Thread 类或子类创建线程对象。

在编写 Thread 类的子类时,需要重写父类的 run() 方法,其目的是规定线程的具体操作,否则线程就什么也不做,因为父类的 run() 方法中没有任何操作语句。

例子

  • 除主线程外还有两个线程,这两个线程共享一个 StringBuffer 对象两个线程在运行期间将修改 StringBuffer 对象中的字符。
  • 为了使结果尽量不依赖于当前 CPU 资源的使用情况,我们应当让线程主动调用 sleep (int n ) 方法让出 CPU 的使用权进入中断状态,
  • sleep(int n) 方法是 Thread 类的静态方法,线程在占有 CPU 资源期间,通过调用 sleep(int n) 方法来使自己放弃 CPU 资源,休眠一段时间
public class People extends Thread {StringBuffer str;People(String s,StringBuffer str) { setName(s); //调用从Thread类继承的setName方法为线程起名字this.str=str;}public void run() {for(int i=1;i<=3;i++) {str.append(getName()+",");   //将当前线程的名字尾加到str 这里有可能被中断System.out.println("我是"+getName()+",字符串为:"+str);try {  sleep(1000); // 中断状态 (TIMED_WAITING)}catch(InterruptedException e){}}} 
}public class Example15_2 {public  static void main(String args[]) {People personOne,personTwo;StringBuffer str=new StringBuffer();personOne=new People("张三",str); personTwo =new People("李四",str); personOne.start();  personTwo.start();}
}

输出(不唯一,每次线程顺序都可能不一样)

我是张三,字符串为:张三,李四,
我是李四,字符串为:张三,李四,
我是李四,字符串为:张三,李四,李四,张三,
我是张三,字符串为:张三,李四,李四,张三,
我是李四,字符串为:张三,李四,李四,张三,李四,张三,
我是张三,字符串为:张三,李四,李四,张三,李四,张三,

15.3 使用 Runnable 接口


还在做笔记中,请稍等~

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

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

相关文章

【Unity的HDRP下ShaderGraph实现权重缩放全息投影_(内附源码)】

实现权重缩放全息投影 效果如下 效果如下 顶点位置偏移 链接&#xff1a; 提取码&#xff1a;1234

Axure RP仿QQ音乐app高保真原型图交互模板源文件

Axure RP仿QQ音乐app高保真原型图交互模板源文件。本套素材模板的机型选择华为的mate30&#xff0c;在尺寸和风格方面&#xff0c;采用标准化制作方案&#xff0c;这样做出来的原型图模板显示效果非常优秀。 原型中使用大量的动态面板、中继器、母版&#xff0c;涵盖Axure中技…

MySql学习笔记01——SQL的相关术语

SQL&#xff08;相关术语&#xff09; 数据库database 有组织的存储数据的容器&#xff0c;通常是一个文件或者一组文件 表table 存储数据的文件称为表&#xff0c;表是某种特定数据的结构化清单。 表可以保存顾客清单、产品目录&#xff0c;或者其他信息清单。 要注意的是&am…

后端常用的Linux命令大全

后端常用的Linux命令大全 基础常用命令 Sudo Command 该命令是“superuser do”的缩写。sudo 是最常用的命令之一&#xff0c;可让你执行需要管理或 root 特权和权限的任务。 使用sudo命令时系统会提示用户重新使用密码进行身份验证。接下来&#xff0c;Linux 系统将记录一…

YAML配置文件

YAML配置文件 SpringBoot中application.properties文件存在的问题&#xff1a;配置太多后难阅读和修改&#xff0c;层级结构辨识度不高。 简介 YAML是"YAML Ain’t a Markup Language"&#xff08;YAML不是一种标记语言&#xff09;的递归缩写。在开发的这种语言时&a…

Matlab信号处理3:fft(快速傅里叶变换)标准使用方式

Fs 1000; % 采样频率 T 1/Fs; % 采样周期&#xff1a;0.001s L 1500; % 信号长度 t (0:L-1)*T; % 时间向量. 时间向量从0开始递增&#xff0c;0s~1.499sS 0.7*sin(2*pi*50*t) sin(2*pi*120*t); % 模拟原信号 X S 2*randn(size(t)); …

汇川PLC学习Day3:轴控代码编写、用户程序结构说明与任务配置示例、用户变量空间与编址

汇川PLC学习Day3&#xff1a;轴控代码编写、用户程序结构说明与任务配置示例、用户变量空间与编址 一、新建轴与轴控代码编写 1. 新建轴 (1)新建一个轴 &#xff08;2&#xff09;将轴名字更新为实际名字 可以后面实例化后再更改&#xff0c;汇川可以在更新名字时同步更新…

艺术与AI:科技与艺术的完美融合

文章目录 艺术创作的新工具生成艺术艺术与数据 AI与互动艺术虚拟现实&#xff08;VR&#xff09;与增强现实&#xff08;AR&#xff09;机器学习与互动性 艺术与AI的伦理问题结语 &#x1f389;欢迎来到AIGC人工智能专栏~艺术与AI&#xff1a;科技与艺术的完美融合 ☆* o(≧▽≦…

Element-ui container常见布局

1、header\main布局 <template> <div> <el-container> <el-header>Header</el-header> <el-main>Main</el-main> </el-container> </div> </template> <style> .el-header { …

第15节-PhotoShop基础课程-吸取工具组

文章目录 前言1.吸管工具 鼠标左键长按吸取外面的点1.取样点2&#xff0c;显示取样环3.画笔工具的时候按住alt可以随时提取画笔颜色 2.颜色取样器工具3.注释工具4.计数工具1.标记大小2.标签大小 前言 1.吸管工具 鼠标左键长按吸取外面的点 自动替换前景色 1.取样点 根据周围点…

MySQL-MHA

目录 1、什么是 MHA 2、MHA 的组成 3、MHA 的特点 3.1 MHA工作原理总结如下 4、搭建 MySQL MHA 4.1 实验环境配置 MHA架构 故障模拟 4.2 安装MHA所有组件 4.3 故障模拟 4.4 总结 1、什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的My…

基于SSM的宿舍管理系统【附源码文档】

基于SSM的宿舍管理系统【附源码文档】 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色&#xff1a;管理员、宿舍管理员、学生 管理员&#xff1a;院系信息、班级信…

springMVC中全局异常处理

前言&#xff1a; 当不同方法执行时&#xff0c;抛出相同异常。为了简约代码和避免重复使用try{}catch{}。此时使用统一异常处理。但局部的统一异常处理只能为所在类所调用。因此产生全局异常处理&#xff0c;该类中统一异常处理方法可以作用于整个controller。&#xff08;以…

docker部署SpringBoot项目

文章目录 1. docker环境1.1 docker安装1.2 docker Web管理工具1.3 docker网络1.3.1 网络说明1.3.2 创建指定网关的网络 2. docker安装软件2.1 安装nginx2.2 安装redis2.3 安装mysql2.4 部署springboot程序2.4.1 编写dockerfile2.4.2 构建镜像2.4.3 启动镜像 1. docker环境 1.1…

C语言程序设计—通讯录实现

本篇文章主要是实现一个简易的通讯录&#xff1a; 功能如下&#xff1a; 添加用户修改用户删除用户查找用户&#xff08;可重名&#xff09;按名字或年龄排序显示用户保存通讯录日志追加 有如下知识点&#xff1a; 动态数组结构体枚举自定义标识符和宏文件打开与存储函数指针…

matlab相机标定求得相机内参

素材下载 可以去官网下载标定板,然后使用我们的相机进行拍照(10~15张即可): 下载请点击这里:here 在拍摄照片之前,先量取对应的每个方格的长度: 如下: 使用MATLAB标定 打开MATLAB的命令行: 输入 cameraCalibrator #调用标定的工具箱 添加的是刚刚我们拍照标定板的…

微信小程序使用editor 富文本编辑器

.wxml <editor id"editor" class"item-content ql-container" placeholder"请输入新闻内容" bindstatuschange"onStatusChange" bindready"onEditorReady" bindinput"onInput" bindblur"onBlur">…

商城系统优化

1、DB、模板的渲染速度&#xff08;thymeleaf&#xff09;、静态资源、日志、JVM 数据库的优化&#xff08;参照数据库优化课程&#xff09;使用索引&#xff0c;减少数据库的交互次数、缓存 thymeleaf使用缓存 静态资源&#xff1a;放到nginx中&#xff0c;实现动静分离 2、…

2023-09-08力扣每日一题

链接&#xff1a; 2651. 计算列车到站时间 题意&#xff1a; 不看日期只看时间 解&#xff1a; &#xff1f; 实际代码&#xff1a; 还看&#xff01;你怎么肥四&#xff1f;int findDelayedArrivalTime(int arrivalTime, int delayedTime) {return (arrivalTimedelayed…