JavaEE初阶---多线程编程(一.线程与进程)

目录

🤣一.线程与进程的概念与联系:

进程的基本概念:

线程的基本概念:

进程和线程的区别与联系:

🙃代码执行实列:

1.通过继承Thread父类来实现多线程

2.通过实现Runnable接口来实现多线程:

3.通过Lambda表达式来实现多线程:

😇Thread类的常见属性和构造方法:


🤣一.线程与进程的概念与联系:

一张漫画,生动阐明进程进程与线程的关系:

进程的基本概念:

  • 什么是进程?→

🧐🧐定义:进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行的程序的实例,包括程序计数器,寄存器和程序变量的当前值。


  • 进程有哪些特征?→

1.进程依赖于程序的运行而存在,进程是动态的,程序是静态的

2.进程是操作系统进行资源分配和调度的一个独立单位(CPU除外,线程是处理器任务调度和执行的基本单位);

3.每个进程拥有独立的地址空间,地址空间包括代码区,数据区和堆栈区,进程之间的地址空间是间隔的,互不影响


线程的基本概念:

  • 什么是线程?

🦉🦉定义:一个线程就是一个“执行流”,每个线程之间都可以按照顺序执行自己的代码,多个线程之间“同时”执行着多份代码

  • 为什么要用到线程?

⾸先, "并发编程" 成为 "刚需":

为了充分利用CPU的资源,避免出现“一核工作,多核围观”的情况,我们可以通过编写特殊的代码,把多个CPU核心,充分利用起来,这样的代码就称为“并发编程”,多进程的编程,就是一种典型的并发编程。虽然多进程能够解决问题,但是随着对于效率的要求越来越高,就希望有更好的方法来实现并发编程。而多进程的编程,最大的问题,就是进程太“重”,创建进程/销毁进程的开销比较大(时间,空间),一旦场景需要频繁的创建和销毁进程,开销就非常明显了→最典型的是服务器开发,针对每一个发出请求的客户端,都创建一个单独的进程,由这个进程负责给客户端提供服务。为了解决进程开销比较大的问题,就发明了线程(Thread),线程可以理解为更加轻量级的进程,也能解决开发并发程序的问题,但是创建/销毁的开销,要比进程更低。

进程和线程的区别与联系:

  • 1.进程包含线程:

一个进程里至少包含一个线程(主线程),也可以包含多个线程。不能没有线程

  • 2.进程是系统分配资源的基本单位

  • 3.线程是系统调度执行的基本单位

  • 4.同一个进程里的线程之间,共用一份系统资源(内存,硬盘,网络宽带等),尤其是内存资源,就是代码中定义的变量/对象等信息,编程中,多个线程,是可以共用同一份变量的~
  • 5.多线程是当下实现并发编程的主流方式,通过多线程,就可以充分利用好多核CPU。但是,也不是线程数目越多,就越好,线程数目达到一定程度,把多个核心都利用充分之后,此时继续增加线程,无法再提高效率,甚至可能会影响效率(线程的调度,也是有开销的)
  • 6.多个线程之间,可能会互相影响,线程安全问题。一个线程抛出异常,也可能会把其他线程一起带走 
  • 7.多个进程之间,一般不会互相影响,一个进程奔溃了,不会影响到其他进程(进程的隔离性)

🙃代码执行实列:

1.通过继承Thread父类来实现多线程

//1.通过继承Thread父类来实现进程
class MyThread extends Thread{
    @Override
    public void run(){
        //这里写的代码,就是即将创建的线程,要执行的逻辑
        while(true){
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                //throw new RuntimeException(e);
                e.printStackTrace();
            }
        }
    }
}
public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        MyThread t = new MyThread();
        //创建线程->运行hello main 和 hello thread 并发执行,同时打印
        t.start();
        //run 不会创建线程,也是再主线程中执行逻辑
        //t.run();只循环打印hello thread
        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

也可以通过匿名内部类来实现:

//通过匿名内部类来创建多线程
public class Demo3 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            @Override
            public void run(){
                while(true){
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t.start();
        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

运行结果:

2.通过实现Runnable接口来实现多线程:

//2.通过实现Runnable接口来实现多线程
class MyRunnable implements Runnable{
    //描述线程里要完成的逻辑是啥
    @Override
    public void run() {
        while(true){
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Demo2 {
    public static void main(String[] args) throws InterruptedException {
        MyRunnable runnable = new MyRunnable();
        Thread t = new Thread(runnable);
        t.start();

        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

也可以通过匿名内部类来实现:

public class Demo4 {
    public static void main(String[] args) throws InterruptedException {
        //通过匿名内部类来编写
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    System.out.println("hello thread");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t.start();
        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

3.通过Lambda表达式来实现多线程:

//通过lambda表达式来进行编写
public class Demo5 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while(true){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t.start();

        while(true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

😇Thread类的常见属性和构造方法:

  • Thread类常见的构造方法:

  • Thread类常见的属性:

public class Demo6 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while(true){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"自定义线程");//->线程名字为自定义线程

        t.start();
        System.out.println("线程ID : " + t.getId());
        System.out.println("线程名字: " + t.getName());
        System.out.println("线程状态: " + t.getState());
        System.out.println("线程执行顺序:" + t.getPriority());
    }
}

运行结果:

Runnable正在运行,实际上Java没有Running这个线程状态,把正在CPU上运行,和随时可以调度到CPU上运行的,都统称为Runnable

  • 前台线程&后台线程

后台线程:如果这个线程执行过程中,不能阻止进程结束(虽然线程执行着,但是进程就要结束了,此时这个线程也会随之被带走)这样的线程就称为“后台线程”

前台线程:如果某个线程执行过程中,能阻止进程的结束,此时这个线程就是“前台线程”

前台线程和后台线程,主要是影响程序的退出

public class Demo7 {
     //设置前
    public static void main1(String[] args) {
        Thread t1 = new Thread(()->{
            while(true){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
    }
     //设置后
    public static void main(String[] args) {
        Thread t2 = new Thread(()->{
           while(true){
               System.out.println("hello thread");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        //把 t 设置线程为后台线程(守护线程),不能在阻止程序结束了
        t2.setDaemon(true);
        t2.start();
    }
}

 结语: 写博客不仅仅是为了分享学习经历,同时这也有利于我巩固知识点,总结该知识点,由于作者水平有限,对文章有任何问题的还请指出,接受大家的批评,让我改进。同时也希望读者们不吝啬你们的点赞+收藏+关注,你们的鼓励是我创作的最大动力!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言题解】1、写一个宏来计算结构体中某成员相对于首地址的偏移量;2、写一个宏来交换一个整数二进制的奇偶位

🥰欢迎关注 轻松拿捏C语言系列,来和 小哇 一起进步!✊ 🌈感谢大家的阅读、点赞、收藏和关注 💕希望大家喜欢我本次的讲解💕 目录👑 1、写一个宏,计算结构体中某变量相对于首地址的偏…

拼多多第37期:拼多多单品裂变起爆2.0(17节课)

课程下载:拼多多第37期:拼多多单品裂变起爆2.0(17节课)-课程网盘链接提取码下载.txt资源-CSDN文库 更多资源下载:关注我。 课程内容: 01.《拼多多单品裂变起爆2.0》非标品类成功操作案例.mp4 02.《拼多…

在Windows上用Llama Factory微调Llama 3的基本操作

这篇博客参考了一些文章,例如:教程:利用LLaMA_Factory微调llama3:8b大模型_llama3模型微调保存-CSDN博客 也可以参考Llama Factory的Readme:GitHub - hiyouga/LLaMA-Factory: Unify Efficient Fine-Tuning of 100 LLMsUnify Effi…

Spring Security系列之Handler

概述 与Spring、Spring MVC、Spring Boot一样,Spring Security里也有很多Handler接口、可以分为两大类,一类是普通的XxxHandler(见名知意),另一类是对应的ServerXxxHandler(RequestRejectedHandler除外&am…

【ArcGIS微课1000例】0119:TIFF与grid格式互相转换

文章目录 一、任务描述二、tiff转grid三、grid转tif四、注意事项一、任务描述 地理栅格数据常用TIFF格式和GRID格式进行存储。TIFF格式的栅格数据常以单文件形式存储,不仅存储有R、G、B三波段的像素值,还保存有地理坐标信息。GRID格式的栅格数据常以多文件的形式进行存储,且…

ElasticSearch学习笔记之三:Logstash数据分析

第3章 Logstash数据分析 Logstash使用管道方式进行日志的搜集处理和输出。有点类似*NIX系统的管道命令 xxx | ccc | ddd,xxx执行完了会执行ccc,然后执行ddd。 在logstash中,包括了三个阶段: 输入input --> 处理filter(不是必须…

【MMU】——ARM 二级页表

文章目录 二级页表项即 entry 的格式如下 二级页表项有三种类型 产生中止异常的故障条目。这可能是预取或数据中止、取决于访问类型。这实际上表示虚拟地址未映射 bit[1:0] 00大页 64KB。bit[1:0] 01。小页 4KB。bit[1:0]1x。 一级页表占用 16KB 的内存,二级页表…

Fastgpt接入Whisper本地模型实现语音输入

前言 FastGPT 默认使用了 OpenAI 的 LLM 模型和语音识别模型,如果想要私有化部署的话,可以使用openai 开源模型Whisper。参考文章 《openai 开源模型Whisper语音转文本模型下载使用》 开源项目地址 : 兼容openai接口api服务 https://gitee.com/taisan/whisper-api 设置安…

glm-4v-9b 部署

glm-4v-9b 模型文件地址 GLM-4 仓库文件地址 官方测试 硬件配置和系统要求 官方测试硬件信息: OS: Ubuntu 22.04Memory: 512G…

【Mac】Media Encoder 2022 for Mac(媒体编码器)V22.6.1软件介绍

软件介绍 Media Encoder 2022 for Mac是一款有着十分丰富硬件设备的编码格式设置和专门设计的预设设置功能的媒体编码器软件,Media Encoder Mac版能够帮助用户导出与特定交付媒体兼容的文件,可以很容易地将项目导出到任何屏幕上的可播放内容中。软件同时…

4.通用编程概念

目录 一、变量与常量1.1 变量1.2 常量 二、遮蔽三、数据类型3.1 标量类型1. 整型2. 浮点型3. 布尔类型4.字符类型 3.2 复合类型1. 元组2. 数组 四、函数五、语句和表达式六、函数的返回值 一、变量与常量 1.1 变量 在Rust中默认的变量是不可变的,如果修改其值会导致…

帮助手册到底是什么?怎么制作?

在当今竞争激烈的商业环境中,提供卓越的客户服务已成为企业脱颖而出的关键。而一个优质的帮助手册,不仅可以帮助企业提高客户服务质量,还能够降低客服成本,提升客户满意度。本文将探讨帮助手册的重要性以及如何利用它来提升企业的…

学习VUE3——组件(二)

组件插槽slots 插槽内容与出口 在某些场景中&#xff0c;我们可能想要为子组件传递一些模板片段&#xff0c;让子组件在它们的组件中渲染这些片段。这时就需要用到插槽。 如下例所示&#xff1a; <!-- Parent.vue --> <FancyButton>Click me! <!-- 插槽内容…

conntrack如何限制您的k8s网关

1.1 conntrack 介绍 对于那些不熟悉的人来说,conntrack简单来说是Linux内核的一个子系统,它跟踪所有进入、出去或通过系统的网络连接,允许它监控和管理每个连接的状态,这对于诸如NAT(网络地址转换)、防火墙和保持会话连续性等任务至关重要。它作为Netfilter的一部分运行,…

如何开发一 VSCode 插件

如何开发一个 VSCode 插件&#xff0c;本文开发一个 VSCode “Hello World” 插件&#xff0c;通过代码了解 VSCode 插件是如何工作的。 安装脚手架 npx --package yo --package generator-code -- yo code根据提示选择&#xff0c;插件开发语言选择 TypeScript ? What type…

网络编程: reactor模式的步步探索与实现

网络编程: reactor模式的步步探索与实现 一.步步探索1.先看一下之前的BUG的影响2.解决拼接式读取问题3.进一步的探索4.Connection的提出5.EpollServer的修改并将监听套接字添加进去6.小演示 二.协议与业务登场1.协议,业务,解决粘包,序列反序列化等等的函数模块实现2.读写异常事…

mac环境基于llama3和metaGPT自动开发2048游戏

1.准备虚拟环境 conda create -n metagpt python3.9 && conda activate metagpt 2.安装metagpt pip install --upgrade metagpt 3.初始化配置文件 metagpt --init-config 4. 安装llama3 5. 修改配置文件 6.让metegpt自动开发2048游戏 7.经过多轮迭代&#xff0c;最终…

彩虹外链网盘图床文件外链系统源码v5.5

彩虹外链网盘&#xff0c;是一款PHP网盘与外链分享程序&#xff0c;支持所有格式文件的上传&#xff0c;可以生成文件外链、图片外链、音乐视频外链&#xff0c;生成外链同时自动生成相应的UBB代码和HTML代码&#xff0c;还可支持文本、图片、音乐、视频在线预览&#xff0c;这…

软件杯 题目:基于深度学习的中文对话问答机器人

文章目录 0 简介1 项目架构2 项目的主要过程2.1 数据清洗、预处理2.2 分桶2.3 训练 3 项目的整体结构4 重要的API4.1 LSTM cells部分&#xff1a;4.2 损失函数&#xff1a;4.3 搭建seq2seq框架&#xff1a;4.4 测试部分&#xff1a;4.5 评价NLP测试效果&#xff1a;4.6 梯度截断…

SwiftUI六组合复杂用户界面

代码下载 应用的首页是一个纵向滚动的地标类别列表&#xff0c;每一个类别内部是一个横向滑动列表。随后将构建应用的页面导航&#xff0c;这个过程中可以学习到如果组合各种视图&#xff0c;并让它们适配不同的设备尺寸和设备方向。 下载起步项目并跟着本篇教程一步步实践&a…