java --- 多线程

目录

一、java多线程的三种实现方式

1.1  多线程的第一种实现方式:继承Thread类

 1.2  多线程的第二种实现方式:Runnable接口

1.3 多线程的第三种实现方式:Callable接口和Future接口

1.3  多线程三种实现方式的对比

二、线程常用的成员方法

2.1  设置/获取线程name、sleep线程

2.2 线程优先级

2.3 守护线程(备胎线程)

三、线程安全问题

3.1 同步代码块

3.2 同步方法

3.3 lock锁

四、死锁

五、生产者消费者模型(等待唤醒机制)

六、线程池

6.1 实现方法:

6.2 自定义线程池


在之前,已经学习了C++的多线程编程,现在一起来看一下java是怎么实现的吧

Linux之多线程概念&线程控制_linux 线程执行到某一函数时,强制另一个线程启动-CSDN博客

一、java多线程的三种实现方式

  1. 继承Thread类的方式进行实现
  2. 实现Runnable接口的方式进行实现
  3. 利用Callable接口Future接口的方式进行实现

1.1  多线程的第一种实现方式:继承Thread类

 1.2  多线程的第二种实现方式:Runnable接口

多线程第二种实现方式:

  1. 自己手动定义一个类去实现Runnable接口
  2.  重写里面的run方法
  3. 创建自己的类的对象。
  4.  创建一个Thread类的对象,并开启线程。

1.3 多线程的第三种实现方式:Callable接口和Future接口

线程第三种实现方式:

  1. 创建一个类MyCallable实现Callable接口。
  2. 重写里面的call方法。( 返回值表示多线程运行结果 )
  3. 创建MyCallable的对象。( 表示多线程要执行的任务 )
  4. 创建FutureTask的对象。( 作用管理多线程运行的结果 )
  5. 创建Thread类的对象,并启动线程。( 表示线程 ) 

特点: 可以获取到多线程运行的结果。

1.3  多线程三种实现方式的对比

优点缺点
继承Thread类变成比较简单,可以直接使用Thread类中的方法可以扩展性较差,不能再继承其他的类
实现Runnable扩展性强,实现该接口的同时还可以继承其他的类编程相对复杂,不能直接使用Thread类中的方法
实现Callable接口

二、线程常用的成员方法

方法名称说明
String getName ( )返回此线程的名称
void setName ( String name )设置线程的名字(构造方法也可以设置名字)
static Thread currentThread ( )获取当前线程的对象
static void sleep ( long time )让线程休眠指定的时间,单位为毫秒
setPriority (int newPriority )设置线程的优先级
final int getPriority ( )获取线程的优先级
final void setDaemon ( boolean on )设置为守护线程
public static void yield ( )出让线程 / 礼让线程
public static void join ( )插入线程 / 插队线程

2.1  设置/获取线程name、sleep线程

public class ThreadDeom {public static void main(String[] args) throws InterruptedException {MyThread mt1 = new MyThread();MyThread mt2 = new MyThread();//在不给线程设置名字的时候,线程也是有默认的名字的//System.out.println(mt1.getName());mt1.setName("火车");mt2.setName("飞机");//mt1.start();//mt2.start();//获取的就是main线程的名字System.out.println(Thread.currentThread().getName());System.out.println("hhhhhhhhhhhhhh");Thread.sleep(1000);//按Alt + Enter直接选择抛出异常System.out.println("hhhhhhhhhhhhhh");}
}

2.2 线程优先级

  • 抢占式调度:CPU执行每一条的线程的时机和执行时间都是不确定的。
  • 非抢占式调度:所有的线程轮流进行,执行时间是差不多的。
System.out.println(mt1.getPriority());System.out.println(mt2.getPriority());mt1.setPriority(10);mt2.setPriority(1);

2.3 守护线程(备胎线程)

final void setDaemon ( boolean on )

三、线程安全问题

Java的线程不安全和C++的是一样的,都是因为多个线程同时访问同一个临界资源

解决办法也是引入锁,Java的锁是synchronized

synchroize(){

}

3.1 同步代码块

3.2 同步方法

就是把synchronized关键字加到方法上

  • 特点1  : 同步方法是锁住方法里面的所有代码
  • 特点2 : 锁对象不能自己指定。 

3.3 lock锁

这个和C++的使用方法几乎是一样的

Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作。

Lock中提供了获得锁和释放锁的方法:

成员方法说明
void lock ( )获得锁
void unlock ( )释放锁

Lock是接口不能直接实例化,这里采用它的实现类 ReentrantLock 实例化。

构造方法说明
ReentrantLock ( )创建一个  ReentrantLock 的实例

四、死锁

java的死锁和C++一样的原因

Linux 多线程安全之----死锁问题_linux 多个 mutex 锁住一个资源出现死锁-CSDN博客

五、生产者消费者模型(等待唤醒机制)

常见方法:

成员方法说明
void wait ( ) 当前线程等待,直到被其他线程唤醒
void notify ( )所及唤醒单个线程
void notifyAll ( )唤醒所有线程

例子:

生产者代码

//Desk.java
public class Desk {// 作用: 控制生产者和消费者的执行//判断桌子上是否有面条: 0:没有 ; 1:有public static int foodFlag = 0;//定义总个数public static int count = 10;//锁对象public static Object lock = new Object();
}//Foodie.java
public class Foodie extends Thread {@Overridepublic void run() {// 1.循环while (true) {// 同步代码块synchronized (Desk.lock) {if (Desk.count == 0) {break;} else {// 先判断桌子上是否有面条if (Desk.foodFlag == 0) {// 没有:等待try {Desk.lock.wait(); // 让当前线程与锁进行绑定} catch (InterruptedException e) {e.printStackTrace();}} else {// 把吃的总数- 1Desk.count--;// 有: 开吃System.out.println("吃货在吃面条,还能再吃" + Desk.count + "碗");// 吃完之后:唤醒厨师继续做Desk.lock.notifyAll();// 修改桌子的状态Desk.foodFlag = 0;}}}}}
}

消费者代码

//Desk.java
public class Desk {// 作用: 控制生产者和消费者的执行//判断桌子上是否有面条: 0:没有 ; 1:有public static int foodFlag = 0;//定义总个数public static int count = 10;//锁对象public static Object lock = new Object();
}//Foodie.java
public class Foodie extends Thread {@Overridepublic void run() {// 1.循环while (true) {// 同步代码块synchronized (Desk.lock) {if (Desk.count == 0) {break;} else {// 先判断桌子上是否有面条if (Desk.foodFlag == 0) {// 没有:等待try {Desk.lock.wait(); // 让当前线程与锁进行绑定} catch (InterruptedException e) {e.printStackTrace();}} else {// 把吃的总数- 1Desk.count--;// 有: 开吃System.out.println("吃货在吃面条,还能再吃" + Desk.count + "碗");// 吃完之后:唤醒厨师继续做Desk.lock.notifyAll();// 修改桌子的状态Desk.foodFlag = 0;}}}}}
}

六、线程池

之前多线程编程的弊端还是挺大的:

弊端一:用到线程的时候就要创建弊端二:用完之后线程消失

因此,我们我们引入线程池

线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。

  1. 创建一个池子,池子中是空的。
  2. 提交任务时,池子会创建新的线程对象,任务执行完毕,线程归还给池子;下次再次提交任务时,不需要创建新的的线程,直接复用已有的线程即可。
  3. 但是如果提交任务时,池子中没有空闲线程,也无法创建新的线程,任务就会排队等待。

6.1 实现方法:

Executors:线程池的工具类通过调用方法返回不同类型的线程池对象。

方法名称说明
public static ExecutorService newCachedThreadPool ( )

创建一个没有上限的线程池

public static ExecutorService newFixedThreadPool ( int nThreads )创建有上限的线程池

6.2 自定义线程池

  • 核心元素一:核心线程的数量不能小于0
  • 核心元素二:线程池中最大线程的数量(最大数量>=核心线程数量)
  • 核心元素三:空闲时间(值)(不能小于0
  • 核心元素四:空闲时间(单位)(用TimeUnit指定
  • 核心元素五:堵塞队列(不能为null
  • 核心元素六:创建线程的方式(不能为null
  • 核心元素七:要执行的任务过多时的解决方案(不能为null

不断的提交任务,会有以下三个临界点:

  1. 当核心线程满时,再提交任务就会排队。
  2. 当核心线程满、队列满时,再来任务就会创建临时线程
  3. 核心线程、队列、临时线程都满,再来任务会被拒绝

6.3 最大并行数

CPU密集型运算

(读取文件操作比较少)

I/O密集型运算

(读取文件操作比较多)

查看最大并行数

public class MyThreadPoolDemo {public static void main(String[] args) {//向Java虚拟机返回可用处理器的数目int count = Runtime.getRuntime().availableProcessors();System.out.println(count); //12}
}

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

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

相关文章

<软考>软件设计师-5计算机网络(总结)

1 网络功能和分类 1-1计算机网络的功能 计算机网络是计算机技术与通信技术相结合的产物,它实现了远程通信、远程信息处理和资源共享。计算机网络的功能:数据通信、资源共享、负载均衡、高可靠性。 1-2计算机网络按分布范围划分 1-3网络的拓扑结构 总线型&#xff0…

深度学习环境配置------windows系统(GPU)------Pytorch

深度学习环境配置------windows系统(GPU)------Pytorch 准备工作明确操作系统明确显卡系列 CUDA和Cudnn下载与安装1.下载2.安装 环境配置过程1.安装Anacoda2.配置环境1)创建一个新的虚拟环境2)pytorch相关库的安装 2.安装VScode1&…

C# Tcplistener,Tcp服务端简易封装

文章目录 前言相关文章前言设计代码简单使用运行结果 前言 我最近有个需求要写Tcp服务端,我发现Tcp服务端的回调函数比较麻烦,简化Tcp的服务,我打算自己封装一个简单的Tcp服务端。 相关文章 C# TCP应用编程三 异步TCP应用编程 C# Tcpclient…

ZLMediaKit的转流流程

zlmediakit的优势就是支持多种媒体容器和媒体协议。我从推流和拉流的两个角度,梳理出了转流的核心骨架。 推流 协议和容器格式的转换,最基本的内核就是音视频数据的扭转。对视频而言就是,解封装帧数据,组帧,封装帧。…

OpenHarmony 启动流程优化

目前rk3568的开机时间有21s,统计的是关机后从按下 power 按键到显示锁屏的时间,当对openharmony的系统进行了裁剪子系统,系统app,禁用部分服务后发现开机时间仅仅提高到了20.94s 优化微乎其微。在对init进程的log进行分析并解决其…

基于CNN+数据增强+残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)+数据集+模型(五)

系列文章目录 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型(一) 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型&#xf…

butterfly蝴蝶分类

一、分类原因 由于植物分类所使用的数据集存在一定问题,修改起来比较麻烦,本次采用kaggle的ButterflyMothsImageClassification数据集,对100这种蝴蝶进行分类。 二、100中蝴蝶类别 ‘ADONIS’,‘AFRICAN GIANT SWALLOWTAIL’,‘AMERICAN S…

基于ssm高校推免报名系统源码和论文

网络的广泛应用给生活带来了十分的便利。所以把高校推免报名管理与现在网络相结合,利用java技术建设高校推免报名管理系统,实现高校推免报名的信息化。则对于进一步提高高校推免报名管理发展,丰富高校推免报名管理经验能起到不少的促进作用。…

Tomcat 部署论坛

一、安装好mysql数据库和jdk之后 开始部署论坛 用Navicat Premium 15连接mysql数据库并创建jforum数据库 下载版本 点击安装选择minninum点击下一步 点击一下一步 选择默认安装路径 安装验证,在安装完毕且启动Apache Tomcat,通过浏览器访问tomcat的80…

【QT】非常简单的登录界面实现

本系列是作者自学实践过程的记录 本文是关于登录界面设计 有问题欢迎讨论 效果图: 一、创建项目和主界面 创建Qt Widget Application 这里我们使用qmake而不是cmake 这是主界面,登录界面等后面再创建,这里要勾选上generate form&#xff0…

如何提高React组件的渲染效率的?在React中如何避免不必要的render?

面试官:说说你是如何提高组件的渲染效率的?在React中如何避免不必要的render? 一、是什么 react 基于虚拟 DOM 和高效 Diff 算法的完美配合,实现了对 DOM 最小粒度的更新,大多数情况下,React 对 DOM 的渲染…

RocketMQ系统性学习-SpringCloud Alibaba集成RocketMQ以及消费收发实战

文章目录 Spring Cloud Alibaba 集成 RocketMQ 最佳实践集成依赖DashBoard消息收发实战 Spring Cloud Alibaba 集成 RocketMQ 最佳实践 SpringBoot 相对于 SSM 来说已经很大程度上简化了开发,但是使用 SpringBoot 集成一些第三方的框架,还是需要花费一些…

Seata使用详解

分布式事务介绍分布式事务的优缺点CAP理论介绍Base理论介绍CAP和BASE之间有什么区别Seata介绍Seata支持的事务模式介绍Seata的架构Seata应用场景Seata集群部署Seata集群部署的优缺点Seata在Java中的使用案例Seata在Java中的代码示例Seata与SpringBoot2.x的整合Seata与SpringBoo…

SpringIOC之BeanExpressionContextAccessor

博主介绍:✌全网粉丝5W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…

NXP应用随记(六):S32K3xx的时钟与PIN简介

目录 1、S32K3基础时钟 1.1、关键功能 1.2、时钟产生模块 1.3、系统时钟 1.4、模式输入模块 1.5、时钟监控模块 2、S32DS时钟与外设配置工具 2.1、创建一个PIT模块 3、IO配置 3.1、IO资源分析 3.2、IO配置工具 1、S32K3基础时钟 S32K3有五个时钟源 1、快速内部 RC 晶…

0基础学java-day22(多用户即时通信系统)

一、QQ 聊天项目演示 聊天通讯系统 在运运行过程出现的异常,应该是类的序列化不一致导致的 1 项目 QQ 演示 2 为什么选择这个项目 只做核心部分,界面相对弱化 3 项目开发流程 3.1 需求分析 3.2 界面设计 3.2.1 用户登录 3.2.2 拉取在线用户列表 …

【C++】对象特性:无参有参构造函数,拷贝构造函数,析构函数

目录 对象的初始化和清理1.1 构造函数和析构函数1.2 构造函数的分类及调用1.3 拷贝构造函数调用时机1.4 构造函数调用规则1.5 深拷贝与浅拷贝 对象的初始化和清理 生活中我们买的电子产品都基本会有出厂设置,在某一天我们不用时候也会删除一些自己信息数据保证安全。…

再看参数校验

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 写一个接口&#xff0c…

管理类联考——数学——真题篇——按题型分类——充分性判断题——蒙猜D

先看目录,除了2018年比较怪,其他最多2个D(数学只有两个弟弟,一个大弟,一个小弟) 文章目录 2023真题(2023-16)-D 2022真题(2022-21)-D-分析选项⇒是否等价⇒是…

issue阶段的选择电路的实现

1-of-M的仲裁电路 为什么要实现oldest-first 功能的仲裁呢? 这是考虑到越是旧的指令,和它存在相关性的指令也就越多,因此优先执行最旧的指令,则可以唤醒更多的指令,能够有效地提高处理器执行指令的并行度,而且最旧的指…