认识及创建线程(Thread)

news2025/4/17 18:15:38

1 概念

1.1线程是什么

线程是CPU调度的基本单位,它是在进程内部运行的执行流,线程比进程粒度更细,调度成本更低

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

1.2为啥要有线程

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

1.单核 CPU 的发展遇到了瓶颈. 要想提高算力, 就需要多核 CPU.而并发编程能更充分利用多核 CPU 资源

2.有些任务场景需要 "等待 IO", 为了让等待 IO 的时间能够去做一些其他的工作, 也需要用到并发编 .

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

创建线程比创建进程更快.

销毁线程比销毁进程更快.

调度线程比调度进程更快.

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

1.3进程和线程的区别(重要)

1.进程是包含线程的. 每个进程至少有一个线程存在,即主线程。

2. 进程和进程之间不共享内存空间. 同一个进程的线程之间共享同一个内存空间.

进程是系统分配资源的最小单位,线程是系统调度的最小单位。

2第一个多线程程序

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

1.每个线程都是一个独立的执行流

2.多个线程之间是 "并发" 执行的.

package thread;

import java.util.Random;

public class ThreadDemo {
    private static class MyThread extends Thread {
        @Override
        public void run() {
            Random random = new Random();
            while (true) {
                // 打印线程名称
                System.out.println(Thread.currentThread().getName());
                try {
                    // 随机停止运行 0-9 秒
                    Thread.sleep(random.nextInt(10));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();

        t1.start();
        t2.start();
        t3.start();

        Random random = new Random();
        while (true) {
            // 打印线程名称
            System.out.println(Thread.currentThread().getName());
            try {
                // 随机停止运行 0-9 毫秒
                Thread.sleep(random.nextInt(10));
            } catch (InterruptedException e) {

                e.printStackTrace();

            }
        }
    }
}

输出结果:

使用jconsole命令观察线程(jconsole在jdk的bin包下)

3.创建线程

方法1:继承Thread类

1.继承Thread来创建一个线程类

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("这里是线程运行的代码"); 
    }
}

2.创建MyThread实例

MyThread t = new MyThread();

3.使用start()方法启动线程

t.start();  // 线程开始运行

方法2:实现Runnable接口

1.实现Runnable接口

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("这里是线程运行的代码");
    }    
}

2. 创建 Thread 类实例, 调用 Thread 的构造方法时将 Runnable 对象作为 target 参数.

Thread t = new Thread(new MyRunnable());

3.使用start()方法启动线程

t.start();  // 线程开始运行

对比上面两种方法:

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

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

其他方式(lambda、匿名内部类)

匿名内部类创建 Thread 子类对象:

// 使用匿名类创建 Thread 子类对象
Thread t1 = new Thread() { 
    @Override
    public void run() {
        System.out.println("使用匿名类创建 Thread 子类对象");
     }
};

 匿名内部类创建 Runnable 子类对象:

// 使用匿名类创建 Runnable 子类对象
Thread t2 = new Thread(new Runnable() { 
    @Override    
    public 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 子类对象");
});

4 多线程的优势-增加运行速度

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

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

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

package thread;

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() {
            @Override
            public 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--;
        }
            // 等待 thread 线程运行结束
            thread.join();

// 统计耗时
            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);


        }
    }

运行结果:

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

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

相关文章

git 命令怎么回退到指定的某个提交 commit hash 并推送远程分支?

问题 如下图&#xff0c;我要回退到 【002】Babel 的编译流程 这一次提交 解决 1、先执行下面命令&#xff0c;输出日志&#xff0c;主要就是拿到提交 commit 的 hash&#xff0c;上图红框即可 git log或者 vscode 里面直接右击&#xff0c;copy sha 2、执行下面命令回退 g…

AOMEI Partition Assistant傲梅分区助手技术员版:专业级的硬盘分区利器

在数字化时代&#xff0c;数据存储和管理变得愈发重要。对于电脑技术员而言&#xff0c;一款功能强大、操作简便的分区工具无疑是提高工作效率的得力助手。而傲梅分区助手技术员版&#xff08;AOMEI Partition Assistant&#xff09;正是这样一款备受赞誉的专业级硬盘分区软件。…

9种单片机常用的软件架构

长文预警&#xff0c;加代码5000多字&#xff0c;写了4个多小时&#xff0c;盘软件架构&#xff0c;这篇文章就够了! 可能很多工程师&#xff0c;工作了很多年&#xff0c;都不会有软件架构的概念。 因为我在做研发工程师的第6年&#xff0c;才开始意识到这个东西&#xff0c;在…

【Linux】对信号产生的内核级理解

一、键盘产生信号 键盘产生信号这里就要涉及一个重要的概念了&#xff0c;叫硬件中断。我这里会粗粒度地说一下键盘产生信号&#xff0c;以及信号被上层软件读到的过程&#xff0c;只是说一下我自己的理解。 1.1、硬件中断 硬件中断是计算机中的一种机制&#xff0c;它允许硬件…

Python 自定义日志输出

Python 有着内置的日志输出模块&#xff1a;logging 使用也很方便&#xff0c;但我们今天不说这个&#xff0c;我们用文件读写模块&#xff0c;实现自己的日志输出模块&#xff1b;这样在项目中&#xff0c;可以存在更高的自由度及更高的扩展性&#xff1b; 先来看看日志输出…

道路积水检查与报警

文章目录 模型训练积水图像数据集yolo训练流程 图像采集图像预处理模型训练参数设置积水检测与分类数据存储界面制作 模型训练 积水图像数据集 收集积水图像&#xff0c;制作数据集。每张图像对应的标注信息&#xff0c;通常包括目标的类别、边界框坐标等。标注数据可以通过标…

SAP的生成式AI

这是一篇openSAP中关于SAP生成式AI课程的笔记&#xff0c;原地址https://open.sap.com/courses/genai1/ 文章目录 Unit 1: Approaches to artificial intelligence概念三种范式监督学习非监督学习强化学习 Unit 2: Introduction to generative AI生成式AI基础模型关系基础模型有…

软件物料清单(SBOM)生成指南 .pdf

如今软件安全攻击技术手段不断升级&#xff0c;攻击数量显著增长。尤其是针对软件供应链的安全攻击&#xff0c;具有高隐秘性、追溯难的特点&#xff0c;对企业软件安全威胁极大。 同时&#xff0c;软件本身也在不断地更新迭代&#xff0c;软件内部成分安全性在持续变化浮动。…

报错:测试报错postman(测试接口)

报错如下 c.e.exception.GlobalExceptionHandler : 异常信息&#xff1a; Content type multipart/form-data;boundary--------------------------952399813172082093419475;charsetUTF-8 not supported 解决&#xff1a; 异常信息 Content type multipart/form-data;boundary…

STM32使用PWM控制舵机

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. 舵机简介 2. 硬件连接 3. 代码实现 3.1 PWM.c 3.2 PWM.h 3.3 Servo.c 3.4 Servo.h 3.5 main.c 3.6 完整工程文件 PWM和OC输出详解&#xff1a; STM32定时器的OC比较和PWM​​​​​​​ 1. …

树莓派学习笔记--树莓派终端基本操作与系统备份(全卡备份,压缩备份)

树莓派终端基本操作 sudo su #切换为超级用户身份 su lyh #切换回普通用户lyh&#xff08;用户名&#xff09;#目录切换命令 pwd #显示当前所在目录 cd ~ #切换到主目录&#xff08;/home/用户名&#xff09;,~也可省略不写 cd dir …

python程序设计语言超详细知识总结

Python 首先 python 并不是简单&#xff0c;什么语言都有基础和高级之分&#xff0c;要想掌握一门语言&#xff0c;必须把高级部分掌握才行。 HelloWorld helloWorld.py print(hello, world)数据类型与变量 变量的数据类型数据类型描述变量的定义方式整数型 (int)整数&…

OpenVINO安装教程 Docker版

从 Docker 映像安装IntelDistribution OpenVINO™ 工具套件 本指南介绍了如何使用预构建的 Docker 镜像/手动创建镜像来安装 OpenVINO™ Runtime。 Docker Base 映像支持的主机操作系统&#xff1a; Linux操作系统 Windows (WSL2) macOS(仅限 CPU exectuion) 您可以使用预…

微软最新季度业绩结果充分说明了云和AI的增长、谷歌和AWS的竞争

微软最新的季度业绩超出了华尔街的各种预期&#xff0c;但对其服务合作伙伴来说&#xff0c;最重要的是这家科技巨头的预期&#xff1a;人工智能不仅能够增长&#xff0c;而且其云产品尚未达到稳定状态——人工智能是云的潜在增长加速器。 周五的一份分析师报告称&#xff0c;…

实现堆的各种基本运算的算法(数据结构)

以小堆为例&#xff0c;大堆就举一反三了。 堆的物理结构就是普通的数组&#xff0c;但是逻辑结构看成了一颗完全二叉树。 小堆&#xff0c;就是树的每一个父节点都小于他的孩子节点。如图中第一排的a与b。大堆&#xff0c;就是树的每一个父节点都大于他的孩子节点。如图中第…

Mysql基础(三)DDL之create table语句

一 create table 创表 说明&#xff1a; create table相关语句从功能上进行讲解补充&#xff1a; 前面已经讲解过相关的约束,已进行相关的铺垫声明&#xff1a; 参考价值较少,了解即可 ① 基本语法 思考&#xff1a; 约束加在哪里? ② 创建新表 强调&#xff1a;使…

node环境创建Vue项目

node环境创建Vue项目 目录 node环境创建Vue项目安装node.js安装Vue创建Vue项目 安装node.js 【1】.官网下载 【2】.选择路径 【3】配置环境变量 后面就是一路next完成安装 【4】测试 cmd输入node指令&#xff0c;显示版本号证明安装成功 安装Vue 【1】安装cnpm 这是由淘宝…

8.SysTick定时器

SysTick为系统滴答定时器 定时器分类 内核级定时器(系统滴答定时器) 延时定时中断(给系统提供时钟节拍)给操作系统提供时基&#xff08;任务调度&#xff09;FreeRTOS UCOS5ms 基本定时器 延时定时中断时间片&#xff08;实现两盏LED灯同时以一个不同速度闪烁&#xff0c;轮询…

超越GPT-4,清华发布网页导航智能体AutoWebGLM

随着大语言模型&#xff08;LLMs&#xff09;的发展&#xff0c;Agent在网络导航等任务中展现出了前所未有的能力。想象一下&#xff0c;一个基于LLM的Agent能够在你享用早餐时为你总结在线新闻&#xff0c;这样的场景已经不再遥不可及。这种将LLMs融入日常任务的做法&#xff…

1Panel - 现代化、开源的 Linux 服务器运维管理面板

产品介绍 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。 1Panel的官方网站&#xff1a;https://1panel.cn 1Panel的GitHub仓库&#xff1a;https://github.com/1Panel-dev/1Panel 体验环境&#xff1a;https://demo.1panel.cn 1Panel 特点 开源特性 Star 数…