多线程编程(1)

news2025/1/17 4:39:33

本篇重点

  1. 了解进程和线程的区别和联系
  2. 使用Java,实现创建线程的五种写法

目录

  • 使用Java进行多线程编程
    • 方法一:继承 Thread, 重写 run
    • 方法二: 实现 Runnable, 重写 run
    • 方法三: 继承 Thread, 重写 run, 使用匿名内部类
    • 方法四: 实现 Runnable, 重写 run, 使用匿名内部类
    • 方法五: 使用 lambda 表达式
  • 进程与线程的区别总结

上一篇博客中重点介绍了进程的调度,本篇让我们一起来学习线程吧!

为什么更加青睐于使用多线程去解决并发的问题?

因为
进程,是比较“重量级”的,它不仅仅速度比较慢而且消耗资源多
创建一个进程,成本比较高
销毁一个进程,成本也比较高
调度一个进程,成本也挺高
所以,多进程编程,可以解决并发的问题,但是并不是一个高效的选择!!!
线程,则是更加轻量的进程(轻量级进程)

线程为什么比进程更加轻量?

  1. 线程与进程共用同一份进程的系统资源(1. 内存空间 2. 文件描述符表)(意味着,对于线程而言,系统资源是已经分配好了的,创建线程就省下了分配资源的开销)

线程
进程包含线程
一个进程里可以有一个线程,或者多个线程
每个线程都是独立的执行流.多个线程之间,也是并发执行的
操作系统,真正调度的,是在调度线程,而不是进程

线程是操作系统调度运行的基本单位 \color{red}{线程是操作系统调度运行的基本单位} 线程是操作系统调度运行的基本单位

多进程与多线程的吃鸡方式
多进程吃鸡方式
在这里插入图片描述
多线程吃鸡方式
在这里插入图片描述
优化吃鸡过程
在这里插入图片描述
再优化吃鸡过程的思考
在这里插入图片描述
如果一个线程出现了问题,那么会发生什么呢??
在这里插入图片描述

进程和线程的区别: \color{red}{进程和线程的区别:} 进程和线程的区别:

  1. 进程包含线程
  2. 进程有自己独立的内存空间和文件描述符表.同一个进程中的多个线程之间,共享同一份地址空间和文件描述符表
  3. 进程是操作系统资源分配的基本单位,线程是操作系统调度执行的基本单位
  4. 进程之间具有独立性,一个进程挂了,不会影响到别的进程;同一个进程里的多线程之间,一个线程挂了,可能会把整个进程带走,影响到其他线程

使用Java进行多线程编程

方法一:继承 Thread, 重写 run

class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("hello t");
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();
    }
}

想要结果更加明显一点可以加个for循环进行标记

class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("hello t  -- "+i);
        }
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();
        for (int i = 0; i < 30; i++) {
            System.out.println("hello main  -- "+i);
        }
    }
}

在这里插入图片描述

可以看出这里是随机进行打印的

使用sleep函数方便进行结果的查看

class MyThread extends Thread{
    @Override
    public void run() {
        while (true) {
            System.out.println("hello t");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ThreadDemo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new MyThread();
        t.start();
        while (true) {
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

上述代码涉及到两个线程

  1. main 方法所对应的线程(一个进程至少得有一个线程)也可以称为主线程
  2. 通过t.start创建的新线程

如何使用工具对进程进行查看呢??

找到你的jdk --> bin --> jconsole.exe
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方法二: 实现 Runnable, 重写 run

class MyRunnable implements Runnable {
    @Override
    public void run() {
        while (true) {
            System.out.println("hello t");
            
        }
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        MyRunnable runnable = new MyRunnable();
        Thread t = new Thread(runnable);
        t.start();
        while (true) {
            System.out.println("hello main");
        }
    }
}

方法三: 继承 Thread, 重写 run, 使用匿名内部类

public class ThreadDemo3 {
    public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                while (true) {
                    System.out.println("hello t");
                }
            }
        };
        t.start();
        while (true) {
            System.out.println("hello main");
        }
    }
}

方法四: 实现 Runnable, 重写 run, 使用匿名内部类

public class ThreadDemo4 {
    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    System.out.println("hello t");
                }
            }
        });
        t.start();
        while(true) {
            System.out.println("hello main");
        }
    }
}

方法五: 使用 lambda 表达式

创建线程最推荐的写法, 使用lambda表达式!! 最简单直观的写法

public class ThreadDemo5 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while(true) {
                System.out.println("hello t");
            }
        },"我的线程");
        t.start();
        while (true) {
            System.out.println("hello main");
        }
    }
}

以上就是多线程的五种写法啦

进程与线程的区别总结

线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元;而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都有若干个线程,至少包含一个线程。

根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位

资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

包含关系:如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的

影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

执行过程:每个独立的进程有程序运行的入口、顺序执行序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行

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

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

相关文章

【剑指offer】数据结构——数

目录 数据结构——数直接解【剑指offer】43. 1&#xff5e;n 整数中 1 出现的次数【剑指offer】44. 数字序列中某一位的数字【剑指offer】49. 丑数【剑指offer】60. n个骰子的点数【剑指offer】62. 圆圈中最后剩下的数字【剑指offer】64. 求12…n 特殊解——分治法 &#xff1a…

【网络】- TCP/IP四层(五层)协议 - 网际层(网络层) - 划分子网、构造超网

目录 一、概述二、分类IP地址不合理的地方三、划分子网四、无分类编址方法 一、概述 前面的文章介绍了网络层的网际协议IP&#xff0c;介绍了IP地址的定义&#xff0c;知道了IP地址分为网络标识(网络地址)、主机标识(主机地址)两部分&#xff0c;也清楚了最初IP地址是按照分类被…

C++ 迷宫问题

文章目录 题目描述输入描述输出描述示例1 答案&#xff1a;代码讲解&#xff1a; 题目描述 在一个给定大小的迷宫中&#xff0c;有一个起点和一个终点&#xff0c;中间夹杂着一些墙壁 如果能走到终点输出 YES 否则输出 NO 输入描述 迷宫的大小 nm&#xff0c;其中 n 表示行数…

[数据结构 -- C语言] 堆(Heap),你小子就是堆,看我如何透彻的将你拿捏

目录 1、堆的概念及结构 1.1 概念&#xff08;概念总是重要的&#xff09; 1.2 结构&#xff0c;分为两种 1.2.1 小堆/小根堆示例 1.2.2 大堆/大根堆示例 2、堆的接口 3、接口实现 3.1 堆的初始化 3.2 堆的销毁 3.3 堆的插入 功能分析&#xff1a; 功能实现&#x…

zabbix动作执行失败 No media defined for user.

问题 zabbix动作执行失败 No media defined for user. 详细问题 解决方案 1&#xff08;导航栏&#xff09;用户 → \rightarrow →报警媒介 → \rightarrow →添加 2 选择类型 → \rightarrow →收件人 → \rightarrow →添加 3 更新 解决原因 笔者由于未点击更新钮导…

【计算机网络】3、IO 多路复用:select、poll、epoll、reactor | 阻塞非阻塞、同步异步

文章目录 一、select()1.1 用法1.1 实战 二、poll()2.1 用法2.2 实战 三、阻塞、非阻塞3.1 非阻塞 IO3.1.1 read()3.1.2 write()3.1.3 accept()3.1.4 connect()3.1.5 非阻塞IO select() 多路复用实战 四、epoll()4.1 epoll_create()4.2 epoll_ctl()4.3 epoll_wait()4.4 实战4.…

GAN在图像转译领域的应用-CycleGANPix2Pix

在之前的博客中向大家介绍了生成对抗网络GAN的相关概念以及条件GAN&#xff0c;DCGAN相关内容&#xff0c;需要的小伙伴可以点击以下链接了解~生成对抗网络GAN_生成对抗网络流程_春末的南方城市的博客-CSDN博客生成对抗网络Generative Adversarial Networks&#xff08;GAN&…

使用Docker安装Guacamole远程网关并配置录像回放

一、参考 guacamole配置guacamole使用Docker安装guacamole在浏览器中播放录像guacamole插件下载 二、环境 操作系统&#xff1a;Anolis OS 8.6 QU1 docker版本&#xff1a;23.0.5 docker compose版本&#xff1a;v2.17.3 docker-image-guacamole&#xff1a;1.5.1 docker-image…

线段树C++详细讲解和个人见解

问题引入 假设有这样的问题&#xff1a;有n个数&#xff0c;m次操作&#xff0c;操作分为&#xff1a;修改某一个数或者查询一段区间的值 数据范围是&#xff08;1 < n, m<1e9)。 这种题大家一看就知道打暴力&#xff0c;但是一看数据范围就知道只能得部分。 我们之前…

STM32F407单片机HAL库CAN2不能接收数据解决方法

最近在使用stm32F407的片子调试can通信&#xff0c;直接在正点原子的代码上修改调试&#xff0c;调试can1的时候&#xff0c;基本没啥问题&#xff0c;收发都正常&#xff0c;使用查询模式和中断模式都可以。但是当修改到can2的时候&#xff0c;可以正常发送数据&#xff0c;但…

@Transactional注解作用,不生效的场景,事务回滚

目录 一、Transactional注解二、注解失效问题1、Transactional 应用在非 public 修饰的方法上2、Transactional 注解属性 rollbackFor 设置错误3、同一个类中方法调用&#xff0c;导致Transactional失效4、捕获异常 三、Transactional回滚1、Transactional2、Transactional(rol…

HUD(抬头显示)的方案介绍

目录 一、基于DLP3030-Q1的HUD电路设计 二、DLP3030-Q1的介绍 三、DLP3030-Q1工作原理 四、DLPC120-Q1DMD 显示控制器 五、TMS320F2802332 位 MCU 六、 HUD显示实例 HUD主板实例 七、HUD的软件环境 一、基于DLP3030-Q1的HUD电路设计 本设计采用了DLP3030-Q1 芯片组&…

H3C IPSec IKE野蛮模式

这里使用H3C模拟器。 H3C IPSec IKE野蛮模式&#xff0c;又称为IKE Main Mode&#xff0c;主要是在第一阶段&#xff08;Phase 1&#xff09;的过程中提供身份保护。它主要用于VPN隧道建立过程中的密钥交换。以下是配置步骤&#xff1a; 创建IKE提案&#xff1a; system-view…

vite源码分析之dev

最近研究socket, 所以就顺便看了一下vite源码, vite的热更新就是根据socket实现的, 所以正好记录一下. 前端任何脚手架的入口,肯定是在package.json文件中,当我们输入script命令时, 会经历什么样的步骤呢? 接下来我们一起来探索一下~~~ 入口-package.json 看下面就是一个普…

【C++】string介绍

String 前言为什么学习string类&#xff1f;string类的常用接口说明string类对象的常见构造析构函数赋值运算符重载[ ] 重载size和length迭代器字符串追加关于容量的函数insert和erasefindreplacec_strrfindfind_first_offind_first_not_offind_last_ofsubstrgetlineto_string …

linux+onenet可视化(图形化步骤)

文章目录 一、ONENET项目搭建1.1 ONENET注册1.2 创建产品与设备1.3 添加数据流 二、可视化配置 OneNET是由中国移动打造的PaaS物联网开放平台。平台能够帮助开发者轻松实现设备接入与设备连接&#xff0c;快速完成产品开发部署&#xff0c;为智能硬件、智能家居产品提供完善的物…

孤儿僵尸守护进程

孤儿僵尸守护进程 1. 孤儿进程&#xff1a;2. 僵尸进程&#xff1a;3. 守护进程&#xff1a;(重点) 1. 孤儿进程&#xff1a; 父进程退出,还没退出的子进程就变成了孤儿进程 不要怕,还有爷爷进程init: 孤儿进程将被init进程所收养&#xff0c;并由init进程对它们完成状态收集…

认识HTTP协议---2

hi,大家好,今天继续为大家带来HTTP协议相关的知识 认识请求报头 &#x1f440;1.header &#x1f440;2.Content-Type,Content-Length &#x1f440;3.User-Agent &#x1f440;4.Referer &#x1f440;5.Cookie机制 小复习 进入正题之前我们先回忆一下之前的知识 http报…

牛客小白月赛73

A&#xff1a;最小的数字 A-最小的数字_牛客小白月赛73 (nowcoder.com) #include<bits/stdc.h> #define endl \n #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define int long long using namespace std; int n, m, k, A, B, N, M, K; const int ma…

22种transforms数据预处理方法

来源&#xff1a;投稿 作者&#xff1a;阿克西 编辑&#xff1a;学姐 建议搭配视频学习↓ 视频链接&#xff1a;https://ai.deepshare.net/detail/p_5df0ad9a09d37_qYqVmt85/6 1.数据增强&#xff08;data augmentation&#xff09; 数据增强又称为数据增广&#xff0c;数据…