多线程的实现和使用场景

article/2024/12/23 17:28:05

多线程的实现和使用场景

  • 一、多线程实现方式
    • 1.1 Thread实现
    • 1.2 Runnable实现
  • 二、多线程的使用场景
    • 1.多线程使用场景
      • 1.1 多线程应该最多的场景:
      • 1.2多线程的常见应用场景:
    • 2.多线程小案列
      • 2.1 多线程计算
      • 2.2 多线程实现卖票小程序
      • 2.3多线程卖票小程序优化
      • 2.4多线程卖票小程序优化升级
  • 总结

一、多线程实现方式

1.1 Thread实现

继承Thread类并重写它的run方法。之后创建这个子类的对象并调用start()方法。下面直接上代码:

/**
*描述
* @author cy
* @date 2021-06-09
* @return
**/
public class TreadTest  extends  Thread{public static void main(String[] args) {//创建两个线程TreadTest thread1 = new TreadTest();TreadTest thread2 = new TreadTest();thread1.start();thread2.start();}@Overridepublic void run() {for (int i = 0;i < 100;i++){//分别打印线程名称和iSystem.out.println("threadName:"+Thread.currentThread()+";i="+i);}}
}

输出结果可以看到两个线程交替打印。线程启动成功。
在这里插入图片描述

1.2 Runnable实现

Runnable的实现方式是实现其接口,下面请看具体的实现代码


/*** @author  cy* @date  2021-06-09*@deprecated  Runnable实现多线程*/
public class RunnableDemoTest {public static void main(String[] args) {//新建两个线程RunnableDemoTest1 r =  new RunnableDemoTest1();new Thread(r).start();new  Thread(r).start();}/*** 通过runnable 方式实现多线程*/
static class  RunnableDemoTest1  implements  Runnable{@Overridepublic void run() {for (int i = 0 ;i < 5 ;i++)System.out.println("threadName:"+Thread.currentThread()+";i="+i);}
}
}

从输出结果中我们可以看到两个线程交替打印。线程启动成功。
在这里插入图片描述

二、多线程的使用场景

1.多线程使用场景

1.1 多线程应该最多的场景:

web服务器本身; 各种专用服务器(如游戏服务器);

1.2多线程的常见应用场景:

1、后台任务,例如:定时向大量(100w以上)的用户发送邮件; 2、异步处理,例如:发微博、记录日志等; 3、分布式计算

2.多线程小案列

2.1 多线程计算

计算一亿个数字之和,在没有学习多线程之前,也是可以实现的,我们可以通过循环一亿次进行累加,最后得出结果。
代码如下:

package trhead;import java.util.Random;/*** 计算一亿个数之和*/
public class SumThreadDemo {private static double [] nums = new double[1_0000_0000];private static Random r  =  new Random();private static  double  result = 0.0,result1 = 0.0,result2 = 0.0;static {for (int i =0;i < nums.length ; i++){nums[i] = r.nextDouble();}}public static void main(String[] args) throws InterruptedException {SumThreadDemo.m1();SumThreadDemo.m2();}/*** 使用单线程计算*/private  static  void m1(){long startTime = System.currentTimeMillis();for (int i = 0;i < nums.length;i++){result += nums[i];}System.out.println(result);long endTime = System.currentTimeMillis();long countTime = endTime - startTime;System.out.println("m1耗时:"+countTime);}/*** 使用多线程计算*/private  static  void m2() throws InterruptedException {Thread thread1 =   new Thread(()->{for (int i = 0;i < nums.length/2;i++){result1 += nums[i];}});Thread thread2 =   new Thread(()->{for (int i = nums.length/2;i < nums.length;i++){result2 += nums[i];}});long startTime = System.currentTimeMillis();thread1.start();thread2.start();thread1.join();thread2.join();System.out.println(result1+ result2);long endTime = System.currentTimeMillis();long countTime = endTime - startTime;System.out.println("m2耗时:"+countTime);}}

从输出结果中可以观察出,两个线程计算结果比单个线程快了将近两倍。如果实际应用中有这种场景,大家可以使用多线程实现。
在这里插入图片描述

2.2 多线程实现卖票小程序

某电影院正在上映某大片,共5张票,而他又有3个售票窗口售票,请设计一个程序模拟该电影院售票。

多线程实现方式1:

package trhead;/**
*描述*  某电影院正在上映某大片,共5张票,* 而他又有3个售票窗口售票,请设计一个程序模拟该电影院售票。
* @author cy
* @date 2021-06-09
* @return
**/
public class TicketTreadTest extends  Thread{//设置票数private  int ticket = 5;public static void main(String[] args) {//创建两个线程TicketTreadTest thread1 = new TicketTreadTest();TicketTreadTest thread2 = new TicketTreadTest();TicketTreadTest thread3 = new TicketTreadTest();thread1.start();thread2.start();thread3.start();}@Overridepublic void run() {while(true){//分别打印线程名称 和 ticket 数System.out.println("threadName:"+Thread.currentThread()+";ticket="+ticket--);if(ticket < 0){break;}}}
}

结果分析:从下图输出结果中可以分析,使用继承Thread类实现卖票,导致每个窗口都卖了五张票,而这个电影院总共才五张票,多线程出现了超卖现象。原因是继承Thread方式,是多线程多实例,无法实现资源的共享
在这里插入图片描述

2.3多线程卖票小程序优化

在2.2的小程序案列中,我们发现了在多线程的环境下, 由于公共资源可能会被多个线程共享, 也就是多个线程可能会操作同一资源. 当多个线程操作同一块资源时, 很容易导致数据错乱或发生数据安全问题,
即: 数据有可能丢失, 有可能增加, 有可能错乱.

我们如何避免这种现象呢?具体看代码:

package trhead;/*** @author  cy* @date  2021-06-09*@deprecated  Runnable实现多线程卖票*/
public class TicketRunnableDemoTest {//设置票数private  static int ticket = 5;public static void main(String[] args) {//新建两个线程RunnableDemoTest1 r =  new RunnableDemoTest1();new Thread(r).start();new  Thread(r).start();}/*** 通过runnable 方式实现多线程*/
static class  RunnableDemoTest1  implements  Runnable{@Overridepublic void run() {while (ticket > 0){saleTicket();}}/*** 实现卖票方法*/public  void  saleTicket(){if(ticket>0){System.out.println("threadName:"+Thread.currentThread()+ "正在出票,余票剩余:"+ticket-- +"张");}}
}
}

结果分析:从下图输出结果中可以分析,实现Runnable接口进行卖票,电影院总共才五张票,多线程卖票正常。原因是实现Runnable方式,是多线程单实例,可实现资源的共享

在这里插入图片描述

2.4多线程卖票小程序优化升级

细心的小伙伴可能会发现,怎么在2.3输出打印的票数不是从大到小排序的,这跟现实中的卖票场景不一样呐。如果想解决这样的问题,就必须使用同步,所谓的同步就是指多个操作在同一个时间段内只有一个线程进行,其他线程要等待此线程完成之后才可以继续执行
下面我们通过对2.3代码进行继续优化,实现真实卖票场景。

 /**
* 通过synchronized实现线程同步* 实现卖票方法*/ public synchronized   void   saleTicket1(){if(ticket>0){System.out.println("threadName:"+Thread.currentThread()+ "正在出票,余票剩余:"+ +ticket-- +"张");}}

结果分析:从下图输出结果中可以分析,通过同步代码的方法进行代码的加锁操作,实现了卖票场景。
在这里插入图片描述


总结

这节主要给大家介绍了多线程的实现以及相应的一些使用场景,并且引入了同步的知识点,下一节主要介绍synchronized关键字的使用。
另外,码字不容易,如果发现小编描述有误,麻烦指摘。


http://chatgpt.dhexx.cn/article/h3LDihEd.shtml

相关文章

子网掩码、网关及网络号与主机号的区分与计算

前言&#xff1a; 当前使用的IP地址有4个字节&#xff08;32bit&#xff09;组成&#xff0c;即IPV4编码方式。每个IP地址包括两部分&#xff1a;网络号和主机号。当分配给主机号的二进制位越多&#xff0c;则能标识的主机数就越多&#xff0c;相应地能标识的网络数就越少&…

计算机网络之ip、子网掩码、网络号、主机号等概念解析

在工作中谈论到计算机网络时&#xff0c;有几个经常出现的术语&#xff0c;比如&#xff1a;ip、子网掩码、网段等等。之前对这些概念的理解都比较模糊&#xff0c;只知其大概意思&#xff0c;随着工作中遇到的网络问题越来越多&#xff0c;有必要详细理解一下计算机网络的基础…

IP地址、子网掩码、网络号、主机号、网络地址、主机地址以及ip段/数字-如192.168.0.1/24是什么意思?

背景知识 IP地址 IP地址被用来给Internet上的电脑一个编号。大家日常见到的情况是每台联网的PC上都需要有IP地址&#xff0c;才能正常通信。我们可以把“个人电脑”比作“一台电话”&#xff0c;那么“IP地址”就相当于“电话号码”&#xff0c;而Internet中的路由器&#xff0…

若尔当型状态空间方程的能控能观判断

若尔当型状态空间方程的能控能观判断 对于若尔当型状态空间方程&#xff1a; 能控充要条件&#xff1a;当且仅当同一特征值对应的每个若尔当块的最后一行对应B矩阵的行向量线性无关。 注:每个特征值均应满足以上条件。 能观充要条件&#xff1a;当且仅当同一特征值对应的每个…

状态空间方程的能控性与能观性判断

状态空间方程的能控性与能观性判断 能控性判断方法 对于状态空间方程&#xff0c;判断是否能控。 注&#xff1a;由于输出在能控性方面不起任何作用&#xff0c;因此在能控性研究中忽略输出方程。 矩阵对任意t>0均非奇异。的“能控性矩阵”行满秩。的矩阵在A的任一特征值…

Matlab:传递函数(含迟延环节)/状态空间方程/z传递函数的构造/运算/转化

1、传递函数 1.1 构造传递函数 &#xff08;1&#xff09; Matlab可以这样构造上式 num[10 30 20]; den[1 12 47 60]; sysctf(num,den) 运行结果 &#xff08;2&#xff09; 根据零极点构造表达式&#xff1a; z[-1 -2]; p[-3 -4 -5]; k10; sysczpk(z,p,k) 运行结果&…

【电机/鼠笼型感应电机】IM模型建立、坐标变换、状态空间方程推导

目录 一、感应电机三相数学模型 1.1 磁链方程 1.2 电压方程 1.3 转矩方程和运动方程 二、坐标变换 2.1 原理 2.2 Clarke变换和逆变换 2.3 Park变换和逆变换 三、感应电机两相数学模型 . 3.1 αβ坐标系中 3.2 dq坐标系中 四、感应电机状态方程 4.1 状态变量的选择 …

c语言 状态空间控制方程,MPC学习笔记1:基于状态空间模型的预测控制(2)

基于估计的无约束预测控制 1.引言 基本上这两个部分都是在线性理论的框架下,利用状态空间法来建模、求解控制律。状态空间模型在理论分析上具有很强的优越性,但实际应用中能直接准确且经济地获取系统状态并不容易。有些状态,尤其是温度(如火箭喷口温度等)只能间接估计,因此…

控制建模matlab练习02:状态空间方程系统

此建模从一个简单的系统&#xff1a;弹簧质量阻尼系统&#xff0c;来学习状态空间方程系统。 m是质量&#xff1b;b是阻尼系数&#xff1b;k是弹簧系数。 此系统的状态空间方程&#xff0c;如下图&#xff1a; 01新建脚本&#xff08;.m文件&#xff09; 我们在matlab主页&a…

卡尔曼滤波(Kalman Filtering)——(3)数据融合 状态空间方程

数据融合 协方差 状态空间方程 观测器 一、数据融合假设举例公式推导过程再次理解 二、状态空间方程阻尼滑块模型1、连续表达式2、离散表达形式3、符号含义 参考文献 一、数据融合 假设举例 假设测量一物体的质量&#xff0c;现在有两个测量设备但是都存在误差且误差服从正态分…

[现代控制理论]2_state-space状态空间方程

[现代控制理论]11_现代控制理论串讲_完结_pdf获取 [现代控制理论]10_可观测性与分离原理_观测器与控制器 [现代控制理论]9_状态观测器设计_龙伯格观测器 [现代控制理论]8.5_线性控制器设计_轨迹跟踪simulink [现代控制理论]8_LQR控制器_simulink [现代控制理论]7_线性控制器设计…

现代控制理论(一) 状态空间方程

文章目录 状态方程和输出方程基本的状态空间方程 线性非线性时变时不变系统的能控能观状态方程的解无输入线性时不变转移矩阵拉普拉斯求转移矩阵 有输入线性时不变 控制什么&#xff1f; 输入u1,u2,u3,…输出y1,y2,y3…的系统。u是控制量&#xff0c;y是响应结果&#xff0c;也…

【离散系统】传递函数和状态空间方程离散化

本文如有错误&#xff0c;恳请指正。 目录 离散系统 采样控制系统 数字控制系统 信号采样 采样定理&#xff08;香农定理&#xff09; 信号保持—零阶保持器 Z变换 Z 变换方法 级数求和法 部分分式法 基本定理 Z反变换 Z反变换方法 长除法 部分分式法&#xff0…

matlab 状态空间的波特图,MATLAB:对于状态空间方程的系统辨识

本文介绍了如何利用MATLAB辨识状态空间方程中的未知参数。 假设我们的被控系统的表达如下: 我们想要通过实验数据辨识出参数K1和K2​,方法如下: 第一步,采集实验数据。 需要的数据包括系统一段时间内的系统输出Y(ts),以及控制量U(ts),这些数据应该是以某个固定的采样频率…

状态空间方程系统建模

以质量弹簧阻尼系统为例&#xff0c;它的动态微分方程之前提到过为&#xff0c; 令此系统的输入等于外力&#xff0c;系统的输出等于位移。 现代控制理论使用状态空间方程的表达方式。 状态空间——一个集合&#xff0c;输入、输出及状态变量&#xff0c;用一系列一阶方程表达…

状态空间方程转换传递函数

对状态空间方程公式(1)进行拉氏变换 对状态空间方程公式(2)进行拉氏变换 公式(5)带入公式(3)&#xff0c;得到输出和输入的关系 最终转换为传递函数表示

现代控制工程笔记(一)控制系统的状态空间描述

文章目录 1. 基本概念2. 系统的状态空间描述状态空间描述框图状态变量选取的非唯一性 3. 由系统微分方程列写状态空间表达式一.微分方程中不包含输入函数的导数项相变量法其他方法&#xff1a; 二.微分方程中包含输入函数的导数项 4. 由传递函数列写状态空间表达式直接实现串联…

鲁迅《狂人日记》全文

看了《觉醒年代》&#xff0c;不觉找到鲁迅的《狂人日记》全文&#xff0c;摘录在这里。 狂人日记 鲁迅 狂人日记序 某君昆仲&#xff0c;今隐其名&#xff0c;皆余昔日在中学时良友&#xff1b;分隔多年&#xff0c;消息渐阙。日前偶闻其一大病&#xff1b;适归故乡&#xff0…

趣味三角——第5章——苍穹和地球的测量

目录 5.1. 三角学在测量天体和地球的应用中发展 5.2. Abraham De Moivre在天体和地球测量中的数学贡献 第5章 天体和地球的测量 5.1. 三角学在测量苍穹和地球的应用中发展 The science of trigonometry was in a sense a precursor of the telescope. It brought farawa…