JavaEE 第1节 认识多线程

本节目标(全是重点,都必须掌握)

1、了解什么是线程、多线程、进程以及他们之间的关系

2、了解多线程的优势以及各种特性

3、用Java掌握多种创建线程的方法

一、线程、多线程、进程

1、概念

1.基本概念

这三个名词的概念可以用一个餐馆的厨房和厨师来进行超级形象的比喻

想象一下一个餐馆的厨房

整个厨房就是一个进程(Process)。这个厨房就是负责给前台客户提供各种菜品的进程。

厨房里得要有厨师吧,“厨房”里的“厨师”就叫做线程(Thread)

如果是一个大型酒店,厨房里的厨师肯定不止一位对吧,那么如果一个厨房里的厨师有好几位,既一个进程里又好几个线程,那么这就叫做多线程。

每一个厨师在厨房可以独自完成自己的任务,这就叫做线程的独立性

每一个厨师在厨房可以同时工作(做自己的菜),这就叫做线程的并行性线程之间是并发执行的

但是每一个厨师都在同一个厨房进行工作(同一个进程),公用一套厨具,一个厨师(线程)如果在用面包机,另一个厨师(线程)可能就不能用了(主要取决于“厨房”获得的资源大小),这就叫做同一进程中的所有线程,资源是共享的。

2.线程、多线程、进程之间的区别

我们在梳理一下刚才所讲的比喻:

厨房——>进程

厨师——>线程

一个厨房多个厨师——>多线程

  • 所以一个进程至少包含一个线程,既主线程。
     
  • 不同的进程之间是不共享资源的(比如硬盘,网络资源等),但是一个进程中的每一个线程共享同一份资源。
     
  • 线程是系统进行任务调度的最小单位。
     
  • 进程是系统进行资源分配的最小单位。
     
  • 一个进程挂了一般不会影响其他进程的正常运行,但是一个进程中的一个线程挂了,可能会影响到这个进程的正常运行!
     
  • 任意一个线程,都可以在创建一个新的线程。
     
  • 线程分为前台线程和后台线程,所有前台线程结束,整个进程才会结束,后台线程的结束,不会影响到进程的运行

注意:前台线程和后台线程除了是否能决定进程能否退出,在其他方面没有任何区别。

2、多线程的优点

首先,还是用刚才厨房和厨师的例子,假如说一个餐厅的客人非常的多,但是这么大的后厨,和这么多的需求只有一个厨师在卖命的炒菜,这显然是会被人骂的,餐厅早晚会倒闭。

为了充分利用厨房的各种资源,把每个厨具都用上,提高出餐效率,就可以请做个厨师同时进行工作。

既,充分利用进程所申请到的硬件资源(尤其是cup内核),多线程并发执行,高效完成任务,避免资源的浪费。

其次,虽然多进程也是可以实现并发编程的,但是进程的创建、调度、销毁速度远远慢与线程。既,线程更加轻量。

二、线程的创建方式

在java中创建线程,首先要了解一个类(Thread)和一个函数式接口(Runnable)

他们都有一个run()方法(Runnable的runf方法是抽象的,Thread的run方法是具体的),想要创建线程,就必须重写这个run()方法,然后把对象赋值给Thread类,通过Thread类的start()方法创建线程。

方式1——继承Thread:

class MyThread extends Thread{@Overridepublic void run(){while(true){System.out.println("MuCreate");}}
}public class Threads {public static void main(String[] args) {MyThread t1=new MyThread();t1.start();while(true){System.out.println("主线程执行");}}
}

运行结果(截取部分)

以上是通过继承的方式。

Thread类有几个构造方法我们必须了解(等一下还会用到一个哦):

方式2——实现Runnable:

Runnable是一个函数式接口,只包含run这一个抽象方法(注意,Thread类中的run是一个具体的方法)

什么是函数式接口?

1、只包含一个抽象方法

2、可以有默认方法、静态方法(jdk8后引入)

3、和普通接口一样定义的变量必须初始化并且默认被public static final修饰

4、可以用@FunctionalInterface来检查其准确性

因此我们需要实现Runnable才能重写run方法:

class MyThread implements Runnable {//实现并重写run@Overridepublic void run() {while (true) {System.out.println("MuCreate");}}
}public class Threads {public static void main(String[] args) {/*下面两种创建方式都可以*///MyThread MyT=new MyThread();//Thread t1=new Thread(MyT);//把接口对消给到Thread的构造方法Thread t1 = new Thread(new MyThread());//把接口对消给到Thread的构造方法t1.start();while (true) {System.out.println("主线程执行");}}
}

运行结果这里不演示了,和Thread的一样。

注意:

1)对于main方法,系统会自动创建一个线程,这个线程叫主线程

2)只有在调用了Thread对象的start方法,才会创建线程,如果调用run方法,那么run方法里的程序实际上是在主线程上运行的。

3)通过start方法创建的线程默认是前台线程(所有前台线程结束JVM才会退出,同时不论后台线程有没有结束,后台线程也会自动退出)

除了以上两种创建线程的方式,下面还有三种创建线程的方法需要学习,都需要学习掌握。

不过不用怕,下面这三种方式本质上没有区别,都是用到的Thread的这个构造方法:

方式3——匿名内部类之Runnable:

本质就是方式2,既用一个类实现Runnable,不过方式3的这个类没有名字。

     Runnable runnable=new Runnable() {@Overridepublic void run() {System.out.println("我是手动创建的线程");}};

这段代码的含义是先创建一个匿名内部类,这个匿名内部类实现了Runnable接口,并且重写了run方法。然后把创建好的匿名内部类对象,重新赋值给了runnable,既向上转型。

然后再创建Thread类,调用刚才给的构造方法即可:

        Runnable runnable=new Runnable() {@Overridepublic void run() {System.out.println("我是手动创建的线程");}};Thread thread=new Thread(runnable);thread.start();

当然也可以在Thread的构造方法中直接进行匿名内部类的编写,省去runnable的创建:

  Thread thread = new Thread(new Runnable() {@Overridepublic void run() {while(true){System.out.println("我是手动创建的线程");}}});thread.start();

这样写的话代码的内聚性更强。
 

方式4——匿名内部类之Thread

本质就是方式1,既用一个类继承Thread,不过方式4的这个类没有名字。

     Thread thread = new Thread(){@Overridepublic void run(){while(true){System.out.println("创建的线程");}}};thread.start();while(true){System.out.println("主线程");}

方式5——匿名内部类之lambda

方式5的创建和方式3其实是一样的,不过这里换成了lambda表达式

通过lambda表达式重写run方法,并创建一个Runnable的对象,通过赋值的方式,传递给Thread

类的构造方法。

   Thread thread = new Thread(() -> {//下面直接编写方法体while (true) {System.out.println("hehe");}});thread.start();

除了这几种,实际上还可以使用Callable\Excuters创建,以后都会学习到,这里先做一个了解即可。


不论是那种创建方式,都需要重写run()方法,run()方法相当于线程入口。

并且都必须通过Thread类调用start()方法才能启动线程,如果调用run()方法是不会创建线程的,它会仍然在主线程中运行run()方法中的程序。

注意:

start()创建的线程,默认都是前台线程,如果不进行命名,默认按照Thread-0、Thread-1这种方式进行取名。


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

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

相关文章

安卓自定义控件

文章目录 引入布局创建自定义控件 引入布局 首先创建一个项目&#xff0c;创建一个空的活动。然后右键单击res/layout创建一个Layout Resource File文件&#xff0c;取名title.xml。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmln…

【Linux】win 环境下进行 linux开发

文章目录 IDE 安装Python开发创建一个新项目安装 Python、pip 和 venv创建虚拟环境&#xff08;建议&#xff09;运行Python 参考文章 想要win 环境下进行 linux开发&#xff0c;需要依赖于wsl。wsl安装可参考上篇文章 【Linux】wsl win安装Linux环境 这里主要介绍在 linux下…

《学会 SpringMVC 系列 · 剖析入参处理》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

【大模型系列】Video-LLaVA(2023.12)

Paper&#xff1a;https://arxiv.org/pdf/2311.10122v2Github&#xff1a;https://github.com/PKU-YuanGroup/Video-LLaVAHuggingface&#xff1a;https://huggingface.co/spaces/LanguageBind/Video-LLaVAAuthor&#xff1a;Bin Lin et al. 北大袁粒团队 文章目录 1 Video-LLa…

各地级市能源消费总量、夜间灯光值数据(2000-2022年)

全国各地级市能源消费总量、夜间灯光值数据&#xff08;2000-2022年&#xff09; 数据年限&#xff1a;2000-2022年 数据格式&#xff1a;excel 数据内容&#xff1a;337个地级市能源消费总量、夜间灯光值数据&#xff0c;包括城市、省份、年份、夜间灯光值&#xff08;总和&am…

基于pytorch的steam游戏评分的线性回归问题分析

前言 相信已经暑假一个月的大家肯定并不陌生上面这个学习软件()&#xff0c;面对琳琅满目的游戏总是让人不知道挑选什么&#xff0c;这时候一个游戏的评分往往便成为了一个玩家选择下载的原因&#xff0c;那么今天我们就来研究研究&#xff0c;steam上一个游戏的种种数据&…

【window10/window11】解决任务管理器有进程无法强制结束情况

以管理员身份启动控制台窗体&#xff0c;然后从任务管理器中查询到你要结束的进程名&#xff0c;然后运行以下命令&#xff08;UniAccessAgent.exe替换成你要结束的进程&#xff09;&#xff1a; wmic process where nameUniAccessAgent.exe delete 此方法可以解决在任务管理…

快速体验LLaMA-Factory 私有化部署和高效微调Llama3模型(曙光超算互联网平台异构加速卡DCU)

序言 本文以 LLaMA-Factory 为例&#xff0c;在超算互联网平台SCNet上使用异构加速卡AI 显存64GB PCIE&#xff0c;私有化部署Llama3模型&#xff0c;并对 Llama3-8B-Instruct 模型进行 LoRA 微调、推理和合并。 快速体验基础版本&#xff0c;请参考另一篇博客&#xff1a;快…

Animate软件基础:在时间轴中标识动画

FlashASer&#xff1a;AdobeAnimate2021软件零基础入门教程https://zhuanlan.zhihu.com/p/633230084 FlashASer&#xff1a;实用的各种Adobe Animate软件教程https://zhuanlan.zhihu.com/p/675680471 FlashASer&#xff1a;Animate教程及作品源文件https://zhuanlan.zhihu.co…

React--》掌握styled-components重塑React样式管理

想象一下&#xff0c;如果你的React组件不仅能自描述其逻辑&#xff0c;还能直接声明自己的样式&#xff0c;这种“所见即所得”的编程体验是不是让人心动不已&#xff1f;styled-components正是这样一把钥匙&#xff0c;它彻底颠覆了我们对React样式管理的传统认知&#xff0c…

CH571F蓝牙orUSB摇杆鼠标

演示视频&#xff1a; 短视频刷个爽 程序基本上是基于官方的例程上改的&#xff0c;用到的例程有&#xff1a;蓝牙的HID_Mouse,USB的CompoundDev&#xff0c;还有ADC&#xff0c;按键中断。 主要原理 就是ADC采集采集摇杆电压&#xff0c;通过蓝牙HID或者USB的HID发送给电脑或…

Java中操作文件

认识⽂件 我们先来认识狭义上的⽂件(file)。针对硬盘这种持久化存储的I/O设备&#xff0c;当我们想要进⾏数据保存时&#xff0c; 往往不是保存成⼀个整体&#xff0c;⽽是独⽴成⼀个个的单位进⾏保存&#xff0c;这个独⽴的单位就被抽象成⽂件的概 念&#xff0c;就类似办公桌…

Parallels Desktop19让你的Mac无缝运行Windows!

大家好&#xff0c;我是你们的科技小伙伴&#xff0c;今天我要给大家安利一款神奇的软件——Parallels Desktop 19虚拟机。这款产品真的是让我眼前一亮&#xff0c;用起来简直不能更爽&#xff01; 让我们来聊聊为什么我们需要一个虚拟机。 想象一下&#xff0c;你是一个Mac用…

多租户系统数据隔离方案

目录 前言 数据行 数据表 基于业务场景 基于数据量 数据库 数据源表 动态数据源 前言 多租户系统是一种将多个客户的数据和应用程序分开的系统&#xff0c;每个客户被视为一个独立的租户&#xff0c;互不干扰。实现多租户系统的关键之一是确保数据的隔离。 数据隔离的…

[云原生]三、Kubernetes(1.18)

主要内容: 1、kubernetes 简介 2、kubernetes 集群搭建  方式搭建  二进制方式搭建 3、 kubeadm kubernetes 核心技术  YAML 文件详解  kubectl 命令工具  Pod  Label  Controller 控制器 …

职业教育大数据实验实训室建设应用案例

大数据作为一种重要的信息技术&#xff0c;对各行各业产生了深远的影响。职业教育作为培养应用型人才的摇篮&#xff0c;建设大数据实验实训室&#xff0c;对于提高学生的数据分析能力和解决实际问题的能力具有重要意义。唯众作为一家专注于教育技术领域的企业&#xff0c;凭借…

从零开始:MySQL安装与配置完全指南

前言 哇&#xff0c;终于进入到令人激动的MySQL环节了 它可以说是你编程生涯中的最佳朋友&#xff0c;因为它总是能存储你的数据&#xff0c;从不说&#xff1a;“我忘记了你的信 息”。而且&#xff0c;它是免费的&#xff0c;不像一些昂贵的数据库&#xff0c;它从不让你的…

量产部落SM2258XT开卡软件,SM2258XT主控128G SSD固态卡死修复

故障现象&#xff1a;连接此固态硬盘后电脑就会卡死&#xff0c;拔掉重新连接概率性显示盘符&#xff0c;显示了之后也不能正常操作&#xff0c;一点击打开&#xff0c;电脑就立马卡死。 解决过程&#xff1a;下载了很多款量产工具&#xff0c;都不能开卡成功&#xff0c;点击…

Elasticsearch 未授权访问漏洞

Elasticsearch 未授权访问漏洞 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的开放源码发布&#xff0c;是当前流行的企业级搜索…

iAppv3无白银会员使用SDK

前言 一个实用小技巧分享给大家。 工具 iapp&#xff1a;百度或点我获取 Mt管理器&#xff1a;百度或点我获取 教程 1.移出“项目路径/apk/lib/”内的全部文件 2.在iapp内测试打包&#xff0c;打包完成后直接返回&#xff0c;不要安装 3.在mt管理器里面点击“项目路径/b…