java中多线程

文章目录

  • 多线程
    • 进程和线程
      • 进程
      • 线程
    • 继承Thread类方式实现多线程
    • 设置线程名字的两个方式
    • 获取正在运行的线程
    • 线程调度模型和线程优先级设置
      • 两种调度模型
      • 优先级设置
    • 线程控制
      • sleep
      • join
      • 守护线程
    • 线程生命周期


多线程

进程和线程

进程

进程:是正在运行的程序

  • 是系统进行资源分配和调用的独立单位

  • 每个进程都具有它自己的存储空间和系统资源

线程

线程:是进程中的单个顺序控制流,是一条执行路径

  • 单线程:一个进程如果只有一条执行路径,则称之为单线程程序

  • 多线程:一个进程如果有多条执行路径,则称之为多线程程序

继承Thread类方式实现多线程

  • 继承 Thread 类

  • 定义一个 MyThread 继承 Thread 类

  • 在 MyThread 类中重写 run() 方法

  • 创建 MyThread 类的对象

  • 启动线程

demo:

定义一个名字为MyThread的类继承Thread类,重新里面的run方法

package com.itxs.demo01;/*** @Classname : MyThread* @Description : TODO 自定义线程 - 继承Thread类* @Author : lin_refuel@qq.com*/
public class MyThread extends Thread {@Override// 当线程被启动时,会自动调用run方法public void run() {for (int i = 0; i < 20; i++) {System.out.println("i = " + i);}}
}

创建测试类demo01

package com.itxs.demo01;/*** @Classname : demo01* @Description : TODO* @Author : lin_refuel@qq.com*/
public class demo01 {public static void main(String[] args) {// 创建线程对象MyThread mt01 = new MyThread();MyThread mt02 = new MyThread();MyThread mt03 = new MyThread();// 通过start方法来启动多线程mt01.start();mt02.start();mt03.start();}
}

运行结果:每个线程里面都是执行三次循环,并没有顺序,而是谁抢到谁执行,
在这里插入图片描述

设置线程名字的两个方式

  1. 调用方法setName()来设置线程名字
  2. 通过构造方法来设置线程名字

demo:

自定义的线程类

package com.itxs.demo01;/*** @Classname : MyThread* @Description : TODO 自定义线程 - 继承Thread类* @Author : lin_refuel@qq.com*/
public class MyThread extends Thread {// 无参构造public MyThread() {super();}/*** 带参数构造,设置每个线程名字* @param name 名字*/public MyThread(String name) {super(name);}@Override// 当线程被启动时,会自动调用run方法public void run() {for (int i = 0; i < 3; i++) {// this当前类,getName表示获取当前类的名字System.out.println(this.getName() + " i = " + i);}}
}

测试类demo01

package com.itxs.demo01;/*** @Classname : demo01* @Description : TODO* @Author : lin_refuel@qq.com*/
public class demo01 {public static void main(String[] args) {// 创建线程对象MyThread mt01 = new MyThread("线程01");MyThread mt02 = new MyThread("线程02");MyThread mt03 = new MyThread();// 设置每个线程的名字的方法setName();
//        mt01.setName("线程01");
//        mt02.setName("线程02");mt03.setName("线程03");// 通过start方法来启动多线程mt01.start();mt02.start();mt03.start();}
}

运行结果:
在这里插入图片描述

获取正在运行的线程

调用下面Thread类中方法,可以获取当前正在运行对象

Thread.currentThread()

main也是一个线程,设置main线程名字,没有办法通过this.getName和this.setName进行设置,只能通过上面的Thread类中方法进行设置获取

demo:

注意run方法中,输出每个线程名字的地方调用了Thread.currentThread()

package com.itxs.demo01;/*** @Classname : MyThread* @Description : TODO 自定义线程 - 继承Thread类* @Author : lin_refuel@qq.com*/
public class MyThread extends Thread {// 无参构造public MyThread() {super();}/*** 带参数构造,设置每个线程名字* @param name 名字*/public MyThread(String name) {super(name);}@Override// 当线程被启动时,会自动调用run方法public void run() {for (int i = 0; i < 3; i++) {// this当前类,getName表示获取当前类的名字// System.out.println(this.getName() + " i = " + i);System.out.println(Thread.currentThread().getName() + " i = " + i);}}
}

测试类demo01: 注意main线程获取的

package com.itxs.demo01;/*** @Classname : demo01* @Description : TODO* @Author : lin_refuel@qq.com*/
public class demo01 {public static void main(String[] args) {// 创建线程对象MyThread mt01 = new MyThread("线程01");MyThread mt02 = new MyThread("线程02");MyThread mt03 = new MyThread();// 设置每个线程的名字的方法setName();
//        mt01.setName("线程01");
//        mt02.setName("线程02");mt03.setName("线程03");// 通过start方法来启动多线程mt01.start();mt02.start();mt03.start();// 获取正在运行的线程对象Thread.currentThread().setName("主线程");// 设置main线程名字for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "i = " + i);}}
}

运行结果:
在这里插入图片描述

线程调度模型和线程优先级设置

两种调度模型

  • 两种线程调度模型

    • 分时调度模型:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间

    • 抢占调度模型:优先让优先级高的线程使用 CPU,如果线程的欧优先级相同,那么随机选择一个,优先级高的线程获取的 CPU 占用时间会相对多一些

    Java 使用的是抢占式的调度模型

优先级设置

Thread 类中设置和获取线程优先级的方法

 getPriority()//返回次线程的优先级
 setProiority()//更改次线程的优先级

demo:

创建一个名字为MyThread类继承Thread类

package com.itxs.demo01;/*** @Classname : MyThread* @Description : TODO 自定义线程 - 继承Thread类* @Author : lin_refuel@qq.com*/
public class MyThread extends Thread {// 无参构造public MyThread() {super();}/*** 带参数构造,设置每个线程名字* @param name 名字*/public MyThread(String name) {super(name);}@Override// 当线程被启动时,会自动调用run方法public void run() {for (int i = 0; i < 50; i++) {// this当前类,getName表示获取当前类的名字// System.out.println(this.getName() + " i = " + i);System.out.println(Thread.currentThread().getName() + " i = " + i);}}
}

测试类demo02 - 查看优先级高的线程是否能更快执行完

package com.itxs.demo01;/*** @Classname : demo02* @Description : TODO 线程优先级测试运行结果* @Author : lin_refuel@qq.com*/
public class demo02 {public static void main(String[] args) {// 创建线程MyThread mt01 = new MyThread("线程01");MyThread mt02 = new MyThread("线程02");MyThread mt03 = new MyThread("线程03");// 设置每个线程优先级mt01.setPriority(Thread.MIN_PRIORITY);// 优先级低mt02.setPriority(Thread.NORM_PRIORITY);// 优先级不变mt03.setPriority(Thread.MAX_PRIORITY); // 优先级最高// 输出每个线程优先级
//        System.out.println(mt01.getPriority());//1
//        System.out.println(mt02.getPriority());//5
//        System.out.println(mt03.getPriority());//10// 开启线程mt01.start();mt02.start();mt03.start();}
}

运行结果: 线程mt03比其他两个线程运行快一点,仅仅一点

线程控制

sleep

sleep:使当前正在执行的线程停留指定的毫秒数

demo:案例:华山论剑

定义一个MyThread类继承Thread类

package com.itxs.demo02;/*** @Classname : MyThread* @Description : TODO* @Author : lin_refuel@qq.com*/
public class MyThread extends Thread {public MyThread() {super();}// 初始化线程名字的构造方法public MyThread(String name) {super(name);}@Overridepublic void run() {for (int i = 1; i <= 20; i++) {System.out.println(Thread.currentThread().getName() + "打出了第" + i + "招");// 调用sleep使其线程执行一次循环后停留1秒try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

sleeptest测试类

package com.itxs.demo02;/*** @Classname : sleepTest* @Description : TODO sleep测试类* @Author : lin_refuel@qq.com*/
public class sleepTest {public static void main(String[] args) {// 创建线程对象MyThread mt01 = new MyThread("黄固");MyThread mt02 = new MyThread("欧阳锋");MyThread mt03 = new MyThread("段智兴");MyThread mt04 = new MyThread("洪七公");// 开启线程mt01.start();mt02.start();mt03.start();mt04.start();}
}

join

join:等待线程结束

package com.itxs.demo03;/*** @Classname : MyThread* @Description : TODO 自定义线程类 - 继承Thread类* @Author : lin_refuel@qq.com*/
public class MyThread extends Thread {public MyThread() {super();}// 设置线程名字public MyThread(String name) {super(name);}@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName()+"报数:"+i);}}
}

test:测试类,注意join的使用,需要抛出异常

package com.itxs.demo03;/*** @Classname : test* @Description : TODO* @Author : lin_refuel@qq.com*/
public class test {public static void main(String[] args) throws InterruptedException {// 三个人报数,第一个人报完数后,其他人才能报数MyThread mt01 = new MyThread("1号");MyThread mt02 = new MyThread("2号");MyThread mt03 = new MyThread("3号");// 开始报数mt01.start();mt01.join();//等待第一个人报数完毕mt02.start();mt03.start();}
}

守护线程

setDaemon(boolean on)

将此线程标记为守护进程,当运行线程都是守护线程时,JVM 将退出

个人理解:主线程里面运行结束,守护线程不会继续执行

例子:老板带三个员工吃饭,老板吃饱后,员工不能继续吃了

demo:

定义MyThread类继承Thread类

package com.itxs.demo04;/*** @Classname : MyThread* @Description : TODO* @Author : lin_refuel@qq.com*/
public class MyThread extends Thread {public MyThread() {super();}// 设置线程对象名字public MyThread(String name) {super(name);}@Overridepublic void run() {for (int i = 1; i <= 50; i++) {System.out.println(Thread.currentThread().getName() + "正在吃" + i + "口");}}
}

定义三个线程设置为守护线程,进行测试,注意守护线程设置方式

package com.itxs.demo04;/*** @Classname : test* @Description : TODO* @Author : lin_refuel@qq.com*/
public class test {public static void main(String[] args) {// 创建三个工人线程MyThread mt01 = new MyThread("1号工人");MyThread mt02 = new MyThread("1号工人");MyThread mt03 = new MyThread("1号工人");System.out.println("吃饭了");// 三个工人线程设置为守护线程,老板说吃饱了,工人就不继续吃了mt01.setDaemon(true);mt02.setDaemon(true);mt03.setDaemon(true);mt01.start();mt02.start();mt03.start();// 主线程:作为老板Thread.currentThread().setName("老板");for (int i = 1; i <5; i++) {System.out.println(Thread.currentThread().getName() + "正在吃第" + i + "口");}System.out.println("老板说吃饱了,咱们走吧");}
}

线程生命周期

  • 新建:创建线程对象(通过 start() 进入下一个环节)

  • 就绪:有执行资格,没有执行权(抢占 CPU 的执行权)

  • 运行:有执行资格,有执行权(可能被其他线程抢走 CPU 的执行权,则回到就绪状态,若遇到阻塞式方法,则失去运行权和执行这个,等待,当阻塞方法调用结束之后,回到就绪状态)

  • 死亡:线程死亡,成为垃圾

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

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

相关文章

LeetCode刷题:142. 环形链表 II

题目&#xff1a; 是否独立解决&#xff1a;否&#xff0c;参考了解题思路解决问题&#xff0c;思考了用快慢指针&#xff0c;栈&#xff0c;统计链表数量定位尾巴节点&#xff08;因为是环形链表所以是死循环&#xff0c;链表数量用while循环统计不出来&#xff09;都没解决 解…

如何将.NET 8.0的ASP.NET Core Web API部署成Windows服务

写在前面 前面写了一篇关于将.NET应用转换成Windows服务的方法&#xff0c;其实真正的目的是为了探索如何将Asp.Net Core Web Api 部署成Windows 服务。基于上一篇的基础&#xff0c;只需把创建 WebApplication 的代码放到 BackgroundService 的ExecuteAsync方法中即可。 其中…

脱离于ASP.NET 和Visual Studio编辑Razor脚本

Razor Pad是一个编辑Razor脚本的工具&#xff0c;脱离于ASP.NET 和Visual Studio。 github地址&#xff1a;https://github.com/RazorPad/RazorPad 如果在编译源码时出现&#xff1a;签名时出错: 未能对 bin\Debug\app.publish\RazorPad.exe 签名。SignTool Error: No certifi…

JavaScript数据类型、判断、检测

JavaScript数据类型 number、string、boolean、null、undefined、symbol、bigint Object【Array、RegExp、Date、Math、Function】 存储方式 1. 基础类型存储在栈内存中&#xff0c;被引用或者拷贝时&#xff0c;会创建一个完全相同的变量。 2. 引用类型存放在堆内存中&…

深度学习笔记(五)——网络优化(1):学习率自调整、激活函数、损失函数、正则化

文中程序以Tensorflow-2.6.0为例 部分概念包含笔者个人理解&#xff0c;如有遗漏或错误&#xff0c;欢迎评论或私信指正。 截图和程序部分引用自北京大学机器学习公开课 通过学习已经掌握了主要的基础函数之后具备了搭建一个网络并使其正常运行的能力&#xff0c;那下一步我们还…

【Linux笔记】自定义一个简单的shell

一、命令行解释器shell的原理 我们已经知道Linux给我们提供了一系列由exec开头的系统调用接口&#xff0c;可以让我们在自己所写的程序中调用各种指令或者我们自己写的其他程序&#xff1a; 而我们的shell命令行解释器也是接收用户输入的指令&#xff0c;然后执行&#xff1a;…

腾讯滑块(1-13,js逆向)

前言&#xff1a;之前打算写的猿人学比赛题系列因为种种原因耽搁了&#xff0c;主要还是比完赛之后热情就少了很多&#xff0c;看到评论区有人说做了这么久才做出一题&#xff0c;这里需要狡辩一下&#xff0c;我虽然菜但是还没到那种地步&#xff0c;比赛两天时间里我跟队友是…

CH341 SPI方式烧录BK7231U

CH341是一个USB总线的转接芯片&#xff0c;通过USB总线提供异步串口、打印口、并口以及常用的2线和4线等同步串行接口。 BK7231U Wi-Fi SOC芯片&#xff0c;内嵌处理器。1. 符合802.11b/g/n 1x1协议 2. 17dBm 输出功率3. 支持20/40 MHz带宽和STBC 4. 支持Wi-Fi STA、AP、…

ftp安装与配置 云服务器 CentOS7

1、FTP的安装 #安装 yum install -y vsftpd#设置开机启动 systemctl enable vsftpd.service#启动 systemctl start vsftpd.service#停止 systemctl stop vsftpd.service#查看状态 systemctl status vsftpd.service 2、配置FTP #修改前先进行备份文件 cp /etc/vsftpd/vsftpd…

腾讯云怎么领取免费云服务器?

腾讯云免费服务器申请入口 https://curl.qcloud.com/FJhqoVDP 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云服务器网txyfwq.com分享2024年最新腾讯云免费…

弟12章 1 网络编程

文章目录 网络协议概述 p164TCP协议与UDP协议的区别 p165 网络协议概述 p164 ipv4&#xff1a;十进制点分制 ipv6&#xff1a;十六进制冒号分隔 TCP协议与UDP协议的区别 p165 tcp协议的三次握手&#xff1a;

行为型设计模式——备忘录模式

备忘录模式 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以方便地回到一个特定的历史步骤&#xff0c;当新的状态无效或者存在问题时&#xff0c;可以使用暂时存储起来的备忘录将状态复原&#xff0c;很多软件都提供了撤销&#xff08;Undo&#xff09;操作…

【教程】微信小程序如何拍摄图片及视频并上传到后台进行存储

需求分析 在微信小程序中需要使用手机拍摄照片以及视频上传到后台进行进一步的操作&#xff0c;需要解决以下两个问题&#xff1a; 微信小程序如何拍摄照片及视频如何将拍摄的照片及视频上传到后台进行存储 解决方案 前端开发&#xff1a;微信小程序原生 后端开发&#xf…

sentinel熔断与限流

文章目录 一、sentinel简介Sentinel 是什么&#xff1f;Sentinel安装 二、sentinel整合工程新建cloudalibaba-sentinel-service8401微服务引入依赖yml配置主启动类添加EnableDiscoveryClient业务类测试 三、sentinel流控规则基本介绍流控模式直接&#xff08;默认&#xff09;关…

Web前端-移动web开发_流式布局

文章目录 移动web开发流式布局1.0 移动端基础1.1浏览器现状1.2 手机屏幕的现状1.3常见移动端屏幕尺寸1.4移动端调试方法 2.0 视口2.1 布局视口 layout viewport2.2视觉视口 visual viewport2.3理想视口 ideal viewport&#xff08;苹果&#xff09;2.4meta标签 3.0 物理像素(手…

十三、QPalette的简单使用(Qt5 GUI系列)

目录 一、设计需求 二、实现代码 三、代码解析 四、总结 一、设计需求 在实际应用中&#xff0c;经常需要改变某个控件的颜色外观&#xff0c;如背景、文字颜色等。Qt提供的调色板类 QPalette 专门用于管理对话框的外观显示。QPalette 类相当于对话框或是控件的调色板&…

记录:排查create_ap偶发无法开启自发AP的问题

背景说明&#xff1a; 系统&#xff1a;Xubuntu16.04&#xff1b;内核&#xff1a;4.14&#xff1b;无线网卡&#xff1a;EDIMAX EW-7822UAC 关于无线网卡的驱动安装和create_ap配置参考博文&#xff1a;Xubuntu16.04系统中使用EDIMAX EW-7822UAC无线网卡开启5G自发AP 目录 问题…

分布式系统的三字真经CAP

文章目录 前言C&#xff08;Consistency 数据一致性&#xff09;A&#xff08;Availability 服务可用性&#xff09;P&#xff08;Partition Tolerance 分区容错性&#xff09;CAP理论最后 前言 你好&#xff0c;我是醉墨居士&#xff0c;我一起探索一下分布式系统的三字真经C…

大数据调度框架Oozie,这个学习网站让你事半功倍!

Oozie是一个基于工作流引擎的开源框架&#xff0c;由Cloudera公司贡献给Apache。它主要用于管理和调度Apache Hadoop作业&#xff0c;支持的任务类型包括Hadoop MapReduce、Pig Jobs等。 Oozie的核心概念包括workflow jobs和coordinator jobs。Workflow jobs是由多个动作&#…

Jmeter 性能-监控服务器

Jmeter监控Linux需要三个文件 JMeterPlugins-Extras.jar (包&#xff1a;JMeterPlugins-Extras-1.4.0.zip) JMeterPlugins-Standard.jar (包&#xff1a;JMeterPlugins-Standard-1.4.0.zip) ServerAgent-2.2.3.zip 1、Jemter 安装插件 在插件管理中心的搜索Servers Perform…