【JavaEE初阶】 多线程(初阶)——壹

文章目录

  • 🌲线程的概念
    • 🚩线程是什么
    • 🚩为啥要有线程
    • 🚩进程和线程的区别
    • 🚩Java 的线程 和 操作系统线程 的关系
  • 😎第一个多线程程序
    • 🚩使用 jconsole 命令观察线程
  • 🎍创建线程
    • 🚩方法一:继承 Thread 类
    • 🚩方法2:实现 Runnable 接口
    • 🚩方法1、2对比
    • 🚩方法3:其他变形
  • 🎋多线程的优势
  • ⭕总结

本节目标

  • 认识多线程
  • 创建多线程

🌲线程的概念

🚩线程是什么

Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

一个线程就是一个 “执行流”. 每个线程之间都可以按照顺讯执行自己的代码. 多个线程之间 “同时” 执行着多份代码。

举个例子:

一家公司要去银行办理业务,既要进行财务转账,又要进行福利发放,还得进行缴社保。
如果只有张三一个会计就会忙不过来,耗费的时间特别长。为了让业务更快的办理好,张三又找来两位同事李四、王五一起来帮助他,三个人分别负责一个事情,分别申请一个号码进行排队,自此就有了三个执行流共同完成任务,但本质上他们都是为了办理一家公司的业务。
此时,我们就把这种情况称为多线程,将一个大任务分解成不同小任务,交给不同执行流就分别排队执行。其中李四、王五都是张三叫来的,所以张三一般被称为主线程(Main Thread)

🚩为啥要有线程

首先, “并发编程” 成为 “刚需”.

  • 单核 CPU 的发展遇到了瓶颈. 要想提高算力, 就需要多核 CPU. 而并发编程能更充分利用多核 CPU
    资源.
  • 有些任务场景需要 “等待 IO”, 为了让等待 IO 的时间能够去做一些其他的工作, 也需要用到并发编
    程.

其次, 虽然多进程也能实现 并发编程, 但是线程比进程更轻量.

  • 创建线程比创建进程更快.
  • 销毁线程比销毁进程更快.
  • 调度线程比调度进程更快.

最后, 线程虽然比进程轻量, 但是人们还不满足, 于是又有了 “线程池”(ThreadPool) 和 “协程”(Coroutine)

关于线程池和协程博主会在后面一一介绍.此处暂时不做过多讨论.

🚩进程和线程的区别

  • 进程是包含线程的. 每个进程至少有一个线程存在,即主线程
  • 进程和进程之间不共享内存空间. 同一个进程的线程之间共享同一个内存空间.

比如之前的多进程例子中,每个客户来银行办理各自的业务,但他们之间的票据肯定是不想让别人知道的,否则钱不就被其他人取走了么。
而上面我们的公司业务中,张三、李四、王五虽然是不同的执行流,但因为办理的都是一家公司的业务,所以票据是共享着的。这个就是多线程和多 进程的最大区别。

  • 进程是系统分配资源的最小单位,线程是系统调度的最小单位
    在这里插入图片描述

🚩Java 的线程 和 操作系统线程 的关系

线程是操作系统中的概念. 操作系统内核实现了线程这样的机制, 并且对用户层提供了一些 API 供用户使用(例如 Linux 的 pthread 库).

Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进行了进一步的抽象和封装

😎第一个多线程程序

感受多线程程序和普通程序的区别:

  • 每个线程都是一个独立的执行流
  • 多个线程之间是 “并发” 执行的

程序代码如下:

class MyThread extends Thread {@Overridepublic void run() {while(true) {System.out.println("hello thread");//休眠一秒try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}
public class TestMian_1 {public static void main(String[] args) {Thread t1 = new MyThread();t1.start();while (true) {System.out.println("hello main");//休眠一秒try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}

以上就是一个简单的多线程的程序

start:真正的创建一个线程(从系统里创建)
MyThread里面的run:描述线程需要干啥

如果按照我们以前的思维,因为我们写的是个死循环,所以应该执行一个语句,但是这是多线程,执行结果如下:
在这里插入图片描述
结果显示交替进行,这就展现出了多线程与普通程序的区别

🚩使用 jconsole 命令观察线程

我们可以使用jdk自带的工具 jconsole查看当前Java进程中所有的线程

操作流程如下:

  1. 第一步,找到jdk
    在这里插入图片描述
  2. 第二步,点进去,找到里面的bin文件点进去
    在这里插入图片描述
  3. 第三步,点击bin文件夹里面的jconsole
    在这里插入图片描述
  4. 第四步,找到你所创建进程在这里插入图片描述
  5. 第五步,遇到以下情况,直接点击不安全连接就好
    在这里插入图片描述
  6. 第六步,点击线程进行查看
    在这里插入图片描述

🎍创建线程

🚩方法一:继承 Thread 类

  1. 继承 Thread 来创建一个线程类
class MyThread extends Thread {@Overridepublic void run() {System.out.println("这里是线程运行的代码");}
}
  1. 创建 MyThread 类的实例
MyThread t = new MyThread();
  1. 调用 start 方法启动线程
t.start(); // 线程开始运行

🚩方法2:实现 Runnable 接口

  1. 实现 Runnable 接口
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("这里是线程运行的代码");}
}
  1. 创建 Thread 类实例, 调用 Thread 的构造方法时将 Runnable 对象作为 target 参数
Thread t = new Thread(new MyRunnable());
  1. 调用 start 方法
t.start(); // 线程开始运行

🚩方法1、2对比

对比上面两种方法:

  • 继承 Thread 类, 直接使用 this 就表示当前线程对象的引用.

  • 实现 Runnable 接口, this 表示的是 MyRunnable 的引用. 需要使用Thread.currentThread()

🚩方法3:其他变形

  • 匿名内部类创建 Thread 子类对象
// 使用匿名类创建 Thread 子类对象
Thread t1 = new Thread() {@Overridepublic void run() {System.out.println("使用匿名类创建 Thread 子类对象");}
};
  • 匿名内部类创建 Runnable 子类对象
// 使用匿名类创建 Runnable 子类对象
Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("使用匿名类创建 Runnable 子类对象");}
});
  • lambda 表达式创建 Runnable 子类对象
// 使用 lambda 表达式创建 Runnable 子类对象
Thread t3 = new Thread(() -> System.out.println("使用匿名类创建 Thread 子类对象"));
Thread t4 = new Thread(() -> {
System.out.println("使用匿名类创建 Thread 子类对象");
});

🎋多线程的优势

增加运行速度

可以观察多线程在一些场合下是可以提高程序的整体运行效率的。

  • 使用 System.nanoTime() 可以记录当前系统的 纳秒 级时间戳.

  • serial 串行的完成一系列运算. concurrency 使用两个线程并行的完成同样的运算

public class ThreadAdvantage {// 多线程并不一定就能提高速度,可以观察,count 不同,实际的运行效果也是不同的private static final long count = 10_0000_0000;public static void main(String[] args) throws InterruptedException {// 使用并发方式concurrency();// 使用串行方式serial();}private static void concurrency() throws InterruptedException {long begin = System.nanoTime();// 利用一个线程计算 a 的值Thread thread = new Thread(new Runnable() {@Overridepublic void run() {int a = 0;for (long i = 0; i < count; i++) {a--;}}});thread.start();// 主线程内计算 b 的值int b = 0;for (long i = 0; i < count; i++) {b--;}// 统计耗时long end = System.nanoTime();double ms = (end - begin) * 1.0 / 1000 / 1000;System.out.printf("并发: %f 毫秒%n", ms);}private static void serial() {// 全部在主线程内计算 a、b 的值long begin = System.nanoTime();int a = 0;for (long i = 0; i < count; i++) {a--;}int b = 0;for (long i = 0; i < count; i++) {b--;}long end = System.nanoTime();double ms = (end - begin) * 1.0 / 1000 / 1000;System.out.printf("串行: %f 毫秒%n", ms);}
}

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

⭕总结

关于《【JavaEE初阶】 多线程(初阶)——壹》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

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

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

相关文章

【Linux】信号屏蔽与信号捕捉的原理与实现(附图解与代码)

这一篇的篇幅可能有点长&#xff0c;如果已经了解了以下两个知识点的同学可以自行跳到第三部分——信号屏蔽的实现。 不太了解的同学希望你们能够静下心来看完&#xff0c;相信一定会有不小的收获。那么话不多说&#xff0c;我们这就开始啦&#xff01;&#xff01;&#xff0…

【ARM CoreLink 系列 5 -- CI-700 控制器介绍 】

文章目录 1.1 什么是 CI-700?1.1.1 关于 CI-7001.1.2 CI-700 特点1.2 全局配置参数1.2.1 寻址能力1.3 组件和配置1.3.1 CI-700 互联的结构1.3.2 Crosspoint(XP)1.3.3 外部接口1.4 组件(Components)1.1 什么是 CI-700? CI-700是一种AMBA 5 CHI互连,具有可定制的网状拓扑结构…

Web server failed to start. Port 8080 was already in use

一、问题 package com.djc.boot;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annota…

计算机网络笔记3 数据链路层

计算机网络系列笔记目录&#x1f447; 计算机网络笔记6 应用层计算机网络笔记5 运输层计算机网络笔记4 网络层计算机网络笔记3 数据链路层计算机网络笔记2 物理层计算机网络笔记1 概述 文章前言 &#x1f497; 站在巨人的肩膀上&#xff0c;让知识的获得更加容易&#xff01…

想做好接口测试,先把这些概念搞清楚了

接口一般来说有两种&#xff0c;一种是程序内部的接口&#xff0c;一种是系统对外的接口。 系统对外的接口 比如你要从别的网站或服务器上获取资源或信息&#xff0c;别人肯定不会把数据库共享给你&#xff0c;他只能给你提供一个他们写好的方法来获取数据&#xff0c;你引用…

PyTorch入门之【AlexNet】

参考文献&#xff1a;https://www.bilibili.com/video/BV1DP411C7Bw/?spm_id_from333.999.0.0&vd_source98d31d5c9db8c0021988f2c2c25a9620 AlexNet 是一个经典的卷积神经网络模型&#xff0c;用于图像分类任务。 目录 大纲dataloadermodeltraintest 大纲 各个文件的作用&…

【java爬虫】使用vue+element-plus编写一个简单的管理页面

前言 前面我们已经将某宝联盟的数据获取下来了&#xff0c;并且编写了一个接口将数据返回&#xff0c;现在我们需要使用vueelement-plus编写一个简单的管理页面进行数据展示&#xff0c;由于第一次使用vue编写前端项目&#xff0c;所以只是编写了一个非常简单的页面。 项目结…

【Spatial-Temporal Action Localization(五)】论文阅读2020年

文章目录 1. Actions as Moving Points摘要和结论引言&#xff1a;针对痛点和贡献模型框架实验 1. Actions as Moving Points Actions as Moving Points (ECCV 2020) 摘要和结论 MovingCenter Detector (MOCdetector) 通过将动作实例视为移动点的轨迹。通过三个分支生成 tub…

使用css制作3D盒子,目的是把盒子并列制作成3D货架

注意事项&#xff1a;这个正方体的其他面的角度很难调&#xff0c;因此如果想动态生成&#xff0c;需要很复杂的设置动态的角度&#xff0c;反正我是折腾了半天没继续搞下去&#xff0c; 1. 首先看效果&#xff08;第一个五颜六色的是透明多个面&#xff0c;第2-3都是只有3个面…

专业图像处理软件DxO PhotoLab 7 mac中文特点和功能

DxO PhotoLab 7 mac是一款专业的图像处理软件&#xff0c;它为摄影师和摄影爱好者提供了强大而全面的照片处理和编辑功能。 DxO PhotoLab 7 mac软件特点和功能 强大的RAW和JPEG格式处理能力&#xff1a;DxO PhotoLab 7可以处理来自各种相机的RAW格式图像&#xff0c;包括佳能、…

SpringBatch适配不同数据库的两种方法

一、配置JobRepository Configuration EnableBatchProcessing public class TaskArrangeConfig extends DefaultBatchConfigurer {Autowiredprivate DataSource dataSource;Autowiredprivate JobLauncher jobLauncher;Autowiredprivate JobExplorer jobExplorer;Autowiredpriv…

计算机毕设 大数据工作岗位数据分析与可视化 - python flask

文章目录 0 前言1 课题背景2 实现效果3 项目实现3.1 概括 3.2 Flask实现3.3 HTML页面交互及Jinja2 4 **完整代码**5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要…