当前位置: 首页 > news >正文

Java多线程编程-基础篇

多线程相关的概念

并发

并发是指在同一时间段内,两个或多个任务在同一个处理器上交替执行,使得在宏观上看起来像是同时进行。并发是通过快速切换任务来模拟同时执行的效果,实际上在任何一个时刻点上只有一个任务在执行。

 也就是说,并发看起来像多个程序同时运行,但真相是CPU一个个按顺序快速执行的结果,给人造成程序在同一时刻都在运行的”假象“,仿佛在并行

并行

并行是指两个或多个事件在同一时刻发生,即多个指令或任务在同一时刻被多个处理器同时执行。在并行计算中,每个处理器都独立地执行任务,互不干扰。

并发就是真的多个程序在同时运行了,现在很多电脑的处理器都是多核处理器,其中多核处理器就是能够完成并行的必要条件 ,因为每个处理器在同一时刻只能处理一个事件,当我们想要达到并发的状态需要多个处理器来分别处理每个事件。

进程

进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

 也就是说,一个程序在运行时就会产生一个进程,这个进程就是这个程序的一切数据和操作的集合,例如当我们打开浏览器时,系统中就会产生一个和浏览器相绑定的进程

线程

线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。

 一个程序运行后会执行各种操作,这种操作就是以线程的方式在计算机系统下执行的,例如我们打开QQ,会产生一个进程,当我们打开一个好友的聊天框又会生成这个进程的聊天框线程来完成发送消息语音通话等任务。

下面来介绍如何在java程序中实现多线程运行

Java中创建线程

1. 通过实现Runnable接口

在Java中提供了Runnable这个接口,我们想要创建新的线程可以定义新的类实现这个接口,然后实现其中的run()方法,在方法中编写我们的业务代码,这个run方法是线程的入口

查看源码我们可以看到它的代码就是这么朴实无华

public interface Runnable {/*** When an object implementing interface <code>Runnable</code> is used* to create a thread, starting the thread causes the object's* <code>run</code> method to be called in that separately executing* thread.* <p>* The general contract of the method <code>run</code> is that it may* take any action whatsoever.** @see     java.lang.Thread#run()*/public abstract void run();
}

然后我们需要知道,java中创建新的进程需要调用Thread类的start方法,但是Runnable接口中也没有start方法呀,但是我们可以创建一个Thread类型的对象,用我们定义的实现了Runnable接口的类当作构造器参数实例化一个Thread类型的对象,然后利用这个对象调用start方法,它会自动调用我们新实现的run方法

查看源码我们可以看到Thread有这样一个构造器,它的参数是Runnable类型,我们知道接口类型可以接收实现了该接口的类的引用,所以我们直接传入我们新定义的类即可

    public Thread(Runnable target) {init(null, target, "Thread-" + nextThreadNum(), 0);}

下面上代码示例,大家可以自己运行试一下

public class ThRTest{public static void main(String []args) throws InterruptedException{Thread thread1=new Thread(new Dog());thread1.start();//调用start方法才会创建一个线程thread1.setName("狗狗线程");//给线程设置一个名字System.out.println(thread1.getName()+"开始执行.......");//get方法可以获取线程的名字,如果我们不自己设置,会有一个默认的名字for(int i=0;i<10;i++){System.out.println("主线程在执行"+i);Thread.sleep(500);//Thread类的静态方法,可以让程序暂停单位时间}}}class Dog implements Runnable{int times=0;@Override   //run方法中定义我们需要多线程执行的代码public void run() {while(true){System.out.println("狗狗线程执行中"+(++times));try {Thread.sleep(500);//Thread类的静态方法,可以让程序暂停单位时间} catch (InterruptedException e) {e.printStackTrace();}if(times==20)break;}}}

上面这个代码,在执行到主函数时会给主函数生成一个主线程,然后当主线程执行到我们调用start方法时会为生成一个新的线程去执行,我这个代码后又写了个循环输出字符串标记,执行这个代码我们可以得到以下结果

这里我们可以看到主函数中的输出代码和我们自己创建的线程中的输出代码是并行执行的,我刚学的时候感觉很神奇,居然还能这么玩,以上代码里面有一些Thread的方法,都很简单大家看注释应该也能看明白这里就不一一解释了。

2.通过继承Thread类

前面我们已经使用过Thread类了,其实Thread类也是实现了Runnable接口,只不过是又新增了一些创建线程相关的方法而已。

我们通过源码查看Thread类的定义

public class Thread implements Runnable 

可以看到它也是实现了接口Runnable

第一个方法中我们最后还是通过Thread类创建了线程,因为start方法只有Thread类中有,所以当我们新定义的类直接继承了Thread类的时候我们就可以直接创建我们定义的类的对象就可,因为大家知道子类会继承父类的方法,所以我们利用这个方法创建线程只需要对上面的代码略作修改

如下:


public class ThRTest{public static void main(String []args) throws InterruptedException{Thread thread1=new Dog();thread1.start();//调用start方法才会创建一个线程thread1.setName("狗狗线程");//给线程设置一个名字System.out.println(thread1.getName()+"开始执行.......");//get方法可以获取线程的名字,如果我们不自己设置,会有一个默认的名字for(int i=0;i<10;i++){System.out.println("主线程在执行"+i);Thread.sleep(500);//Thread类的静态方法,可以让程序暂停单位时间}}}class Dog extends Thread{int times=0;@Override   //run方法中定义我们需要多线程执行的代码public void run() {while(true){System.out.println("狗狗线程执行中"+(++times));try {Thread.sleep(500);//Thread类的静态方法,可以让程序暂停单位时间} catch (InterruptedException e) {e.printStackTrace();}if(times==20)break;}}}

结果和上面的一样这里就不展示了

为什么会有两种创建方法

很多朋友很疑惑为什么会有好几种方式创建线程,这两种方法的区别和连续??

我们可以看到两种方法,一个是通过实现接口,一个是通过继承,提到继承我们就自然而然的离不开Java的继承规则,不允许多继承,即每个类最多只能继承一个类,那如果我们新定义的Dog类继承自Animal类我们就只能利用实现Runnable接口的方式来创建线程了,算是对java继承机制的一个弥补,方便用户编程,因为现实中很多类都需要继承别的类,所以一般情况下都是利用实现接口这个方法。

实现接口类创建线程的优点

我们来看实现接口类创建线程的代码

        Dog dg=new Dog();Thread thread1=new Thread(dg);thread1.start();//调用start方法才会创建一个线程

我们只需要给Thread构造器传一个参数就可以创建线程,那么当我们需要创建大量的相同的线程时,我们就可以利用这个方式,只需要创建一个Dog类对象,然后重复创建Thread即可,如果是继承的方式,每生成一个线程我们都需要生成一个新的对象,相对来说减少了内库占用,也显得代码更加简洁实用。

总结

多线程在实际的应用程序中法非常常用,例如我们在12306买票就是一个多线程的过程,每个准备抢票的人的手机上都会生成一个抢票线程,当全国几亿人同时访问这个软件,它如何能不出错,保证系统运行正常呢,这里面涉及的并发并行和多线程知识非常之多。希望大家都要学好这一块的知识,学习在路上,加油!

相关文章:

Java多线程编程-基础篇

多线程相关的概念 并发 并发是指在同一时间段内&#xff0c;两个或多个任务在同一个处理器上交替执行&#xff0c;使得在宏观上看起来像是同时进行。并发是通过快速切换任务来模拟同时执行的效果&#xff0c;实际上在任何一个时刻点上只有一个任务在执行。 也就是说&#xff0…...

【极限、数学】 NOIP 2018 提高组初赛试题 第 7 题详解(线段长度期望)

在一条长度为 1 1 1 的线段上随机取两个点&#xff0c;则以这两个点为端点的线段的期望长度是&#xff08; &#xff09;。 考虑将一个线段上平均分布有 n ( n ≥ 2 ) n(n\geq 2) n(n≥2) 个节点&#xff0c;其中首尾均有一个节点&#xff0c;那么我们就将一个线段均分为 n…...

《论网络安全体系设计》写作框架,软考高级系统架构设计师

论文真题 随着社会信息化的普及&#xff0c;计算机网络已经在各行各业得到了广泛的应用。目前&#xff0c;绝大多数业务处理几乎完全依赖计算机和网络执行&#xff0c;各种重要数据如政府文件、工资档案、财务账目和人事档案等均依赖计算机和网络进行存储与传输。另一方面&…...

这款开源的通用PDF处理神器,功能炸裂!

今天分享一款以PDF为中心的多功能办公学习工具箱软件&#xff0c;包含四大板块功能&#xff1a;PDF实用工具箱、Anki制卡神器、Anki最强辅助、视频笔记神器&#xff0c;软件功能众多且强大&#xff0c;熟练运用可以大幅提高办公和学习效率&#xff0c;绝对是您不可多得的效率神…...

RabbitMQ延迟消息——DelayExchange插件

什么是死信以及死信交换机 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信&#xff1a; 1. 消费者使用basic.reject或 basic.nack声明消费失败&#xff0c;并且消息的requeue参数设置为false 2. 消息是一个过期消息&#xff0c;超时无人消费 3. 要投递的队列消…...

【系统规划与管理师】【案例分析】【考点】【答案篇】第5章 IT服务部署实施

【问题篇】☞【系统规划与管理师】【案例分析】【考点】【问题篇】第5章 IT服务部署实施 【移动端浏览】☞【系统规划与管理师】【案例分析】【模拟考题】章节考题汇总&#xff08;第5章&#xff09;&#xff08;答案篇&#xff09;&#xff08;共24个知识点&#xff09; 第5章…...

华为云服务器的数据库部署及管理

不管是终端数据上报到服务器进行存储&#xff0c;还是客户端的动态请求都需要用到数据库&#xff0c;因此这里对数据库的使用进行了一些记录&#xff0c;租用的是华为云的ECS弹性服务器&#xff08;Ubuntu18&#xff09;。下面以网页登录的账号信息Acount为例。 一、Mysql的安装…...

C#【必备技能篇】替换一个字节(byte)中连续几位(bit)的内容

文章目录 一、一个示例二、通用方法 一、一个示例 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApp1 {class Program{static void Main(string[] args){Method1();}public static…...

roboguide将tp程序转化为LS文本格式的方法

不同的软件版本可能操作不同&#xff0c;但是仍然可以参考文章中的办法。 我使用的版本如图所示&#xff1a; 1.首先&#xff0c;打开任意一个工程&#xff0c;如果没有&#xff0c;可以打开自带的示例。 如图&#xff0c;我打开了自带的示例&#xff0c;在帮助文档中可以找到…...

基于SpringBoot+Vue+MySQL的流浪猫狗宠物救助救援网站管理系统

系统展示 用户前台界面 管理员后台界面 系统背景 在当今社会&#xff0c;随着宠物数量的激增及人们关爱动物意识的提升&#xff0c;流浪猫狗问题日益严峻。为解决这一问题&#xff0c;构建一套高效、便捷的流浪猫狗宠物救助救援网站管理系统显得尤为重要。本系统基于SpringBoot…...

I/O 多路复用:`select`、`poll`、`epoll` 和 `kqueue` 的区别与示例

I/O 多路复用是指在一个线程内同时监控多个文件描述符&#xff08;File Descriptor, FD&#xff09;&#xff0c;以便高效地处理多个 I/O 事件。在 UNIX/Linux 和 BSD 系统中&#xff0c;select、poll、epoll、kqueue 都是实现 I/O 多路复用的系统调用。它们各有特点&#xff0…...

大数据之Flink(三)

9.3、转换算子 9.3.1、基本转换算子 9.3.1.1、映射map 一一映射 package transform;import bean.WaterSensor; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator; impor…...

【HCIA-Datacom】IPv4地址介绍

| | &#x1f449;个人主页&#xff1a;Reuuse 希望各位多多支持&#xff01;❀ | &#x1f449;HCIA专栏博客 | 最后如果对你们有帮助的话希望有一个大大的赞&#xff01; | ⭐你们的支持是我最大的动力&#xff01;⭐ | 目录 IPv4地址定义IPv4地址分类方式二级目录三级目录 I…...

maven父子工程多模块如何管理统一的版本号?

1.为什么要统一管理&#xff1f; maven父子工程多模块&#xff0c;每个模块还都可以独立存在&#xff0c;子模块往往通常希望和父工程保持一样的版本&#xff0c;如果每个工程单独定义版本号&#xff0c;后期变更打包也非常麻烦&#xff0c;如何维护一个全局的版本号呢&#x…...

JavaScript --函数的作用域(全局和局部)

全局作用域 全局作用域&#xff0c;就算不在一个script标签也能调用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta nam…...

贪吃蛇项目实现(C语言)——附源码

前言 贪吃蛇是一款十分经典的游戏&#xff0c;其通过控制贪吃蛇的上下左右移动来吃食物&#xff0c;延长自己的身体&#xff0c;也会因为撞到墙体和自身而死亡。下面我们通过C语言来实现贪吃蛇。 1.技术要点 C语言枚举&#xff0c;结构体&#xff0c;链表&#xff0c;动态内…...

【C++】42道面试经典问题总结

C this指针是干什么用的&#xff1f; 假如一个类型定义了很多对象&#xff0c;类里面有很多定义的私有成员变量&#xff0c;共享一套成员方法。通过this指针这可以区分方法、变量是操作的哪个对象的。 C的new和delete&#xff0c;new[]和delete[]可以混用吗&#xff1f; 一般来…...

php 实现JWT

在 PHP 中&#xff0c;JSON Web Token (JWT) 是一种开放标准 (RFC 7519) 用于在各方之间作为 JSON 对象安全地传输信息。JWT 通常用于身份验证系统&#xff0c;如 OAuth2 或基于令牌的身份验证。 以下是一个基本的 PHP 实现 JWT 生成和验证的代码示例。 JWT 的组成部分 JWT …...

vue table id一样的列合并

合并场景&#xff1a;如果id一样&#xff0c;则主表列合并&#xff0c;子表列不做合并&#xff0c;可实现单行、多行合并&#xff0c;亲测&#xff01;&#xff01;&#xff01; 展示效果如图示&#xff1a; 组件代码&#xff1a; // table组件 :span-method"objectSpa…...

xshell密钥方式连接阿里云Linux

前提条件 有阿里云ECS linux实例安装好xshell工具 步骤 创建密钥对并绑定ECS实例 浏览器登录阿里云-->控制台-->ECS服务器-->网络与安全-->密钥对-->创建密钥对 根据提示填写密钥名称-->选中默认资源组-->创建 创建完成&#xff0c;会自动下载密钥对的…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...