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…

C++ 链表实现栈、队

链表实现栈 // 链表实现栈 #include<iostream> using namespace std;// 链表节点 class Node { public:int data;Node* next;Node(){}Node(int data):data(data),next(nullptr){} };// 链表栈 class ListStack { public:Node* top;int count; public:ListStack();void …

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

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

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

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

ES elasticsearch-analysis-dynamic-synonym连接数据库动态更新synonym近义词

ES elasticsearch-analysis-dynamic-synonym连接数据库动态更新synonym近义词 修改源码实现连接数据库获取近义词汇 下载elasticsearch-analysis-dynamic-synonym打开项目(https://github.com/bells/elasticsearch-analysis-dynamic-synonym/tree/master) 一、修改pom.xml …

ZLMediaKit的转流流程

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

OpenHarmony 启动流程优化

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

ax650使用ax-pipeline进行推理

ax650使用ax-pipeline进行推理 ##搭建交叉编译环境 拉取ax-pipeline源码及子模块 git clone --recursive https://github.com/AXERA-TECH/ax-pipeline.git下载sdk cd ax-pipeline ./download_ax_bsp.sh ax650 cd ax650n_bsp_sdk wget https://github.com/ZHEQIUSHUI/assets…

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

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

butterfly蝴蝶分类

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

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

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

可以应用于点云的深度学习方法

点云处理中应用深度学习方法正变得越来越流行&#xff0c;特别是在任务如分类、分割、检测和重建等领域。下面列出了一些在点云处理中常用的深度学习方法&#xff1a; PointNet 和 PointNet&#xff1a; PointNet 是首个直接在点云上工作的深度学习模型。它能够从整个点集中直接…

Tomcat 部署论坛

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

C++/Qt如何处理程序崩溃

在 C 中&#xff0c;程序崩溃时可以通过信号处理机制来捕获崩溃信号&#xff0c;并在程序崩溃时给用户一个提示。以下是一个简单的示例&#xff1a; cpp #include <csignal> #include <iostream> void signalHandler(int signal) { std::cerr << &quo…

动态规划 - 70.爬楼梯(C#和C实现)

动态规划 - 70.爬楼梯(C#和C实现) 题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 注意&#xff1a; 给定 n 是一个正整数。 示例 1: 输入&#xff1a; 2 输出&#xff1a; 2 解释&…

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

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

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

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

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

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

Seata使用详解

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

SpringIOC之BeanExpressionContextAccessor

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