线程的介绍

首先我们来了解一下线程是什么:

首先我们介绍一下程序是什么?程序就是我们编写的代码就叫程序,当我们程序运行的时候则称为进程,在我们现实生活中哪些用到了进程,就比如说我们qq,微信,百度网盘等等软件的使用,当它们在运行的时候,操作系统就会自动的给它们分配内存空间,那线程是什么,线程是由进程创建出来的,是进程的一个实体,一个进程可以拥有多个线程,线程分为两种一个是单线程,还有一个多线程。

单线程:同一时刻,只允许运行一个线程。

多线程:同一时刻,允许运行多个线程,比如qq,微信可以打开多个聊天框,百度网盘可以同时下载多个文件。

接下来我们来介绍两个新的概念:并发和并行

1.并发:同一时刻,多个任务交替执行,但是交换的速度会非常快,让我们感觉是在一块运行的一样,简单来说就像我们的大脑,在我们同时做多件事的时候大脑是迅速的来回切换的,单核cpu实现的多任务就是并发。

2.并行:同一时刻,多个任务同时进行,每个任务都有单独的cpu来执行,即多核cpu实现的多任务就是并行。

接下来我们就要来了解一下线程的使用方式:

首先我们来看一下体系图:

这里我们可以得出创建线程的方式应该有两种:

一个是继承Thread类,还有一种就是实现Runnable接口。

我们先看一下继承Thread类的使用方法:

我们先来看一下实例代码:

public class ift{
    public static void main(String[] args) {
        Preson2 preson1 = new Preson2();
        preson1.start();
    }
}

class Preson2 extends Thread{
    int times= 0;
    @Override
    public void run(){
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("hello" + (times ++));
            if (times == 20){
                break;
            }
        }
    }
}

当我们继承Thread类的时候,我们必须要重写run()方法,否则的话,就会出现报错,但是我们在main方法中,发现我们创建对象之后并没有调用run方法而是调用了start()方法,这里我们来做一个解释,并且对源码进行分析:

当我们调用start()方法的时候我们发现代码自动的调用到了start0()这个方法中,其实start0方法才会调用run()方法,但是它是如何调用的,这个调用过程我们是无法看到的,简单来说是start0()方法调用虚拟机,jvm就会自动的调用run()方法,底层是通过C/C++实现的,所以当我们执行start()方法的时候run方法就会被自动调用,但是run()方法并不是启动线程的方法,它只是编写了线程该执行任务,真正启动线程的还是start()方法(感兴趣的可以Degbug源码),接下来我们来看一下代码的运行示意图:

public class ift extends Thread{
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        Preson2 preson1 = new Preson2();
        preson1.start();
        int time = 0;
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("hi~" + (time ++));
            if (time == 10){
                break;
            }
        }
    }
}

class Preson2 extends Thread{
    int times= 0;
    @Override
    public void run(){
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("hello" + (times ++));
            if (times == 5){
                break;
            }
        }
    }
}

这里我们发现主线程调用start方法后它是不会停止运行的,而是和子线程交替运行,只有两个线程的任务全部结束,才会退出程序。

第二种实现Runable接口的方式。

总所周知,Java的继承是单继承的方式,但是如果我们的类已经继承了其他父类这种情况我们就需要使用我们的接口来实现。

实际案例:

这里我们发现当我们实现Runable接口后我们的start()方法就无法使用了,那我们该如何启动线程,我们来演示一下:

这里我们相当于把它放在一个线程里包装一下,之后就可以使用start()方法。

我们来模拟一下start()调用过程:

class ThreadProxy implements Runnable {//你可以把 Proxy 类当做 ThreadProxy
    private Runnable target = null;//属性,类型是 Runnable
    @Override
    //这里就是一个模拟的一个run()方法,首先判断传入的对象是否为null,不为null的话就会直接调用传入对象的run()方法。
    public void run() {
        if (target != null) {
            target.run();//动态绑定(运行类型 Tiger)
        }
    }
    //我们创建线程调用的构造器,传入一个实现接口Runable的对象
    public ThreadProxy(Runnable target) {
        this.target = target;
    }
    //当我们调用start()方法的时候自动调用start0()方法
    public void start() {
        start0();//这个方法时真正实现多线程方法
    }
    //start0()会调用run()方法
    public void start0() {
        run();
    }
}

大概就是这么个意思,线程的其他具体内容后面再继续写。

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

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

相关文章

Spring容器中scope为prototype类型Bean的回收机制

文章目录 一、背景二、AutowireCapableBeanFactory 方法 autowireBean 分析三、Spring 容器中 scope 为 prototype 类型 Bean 的回收机制四、总结 一、背景 最近做 DDD 实践时,遇到业务对象需要交给 Spring 管理才能做一些职责内事情。假设账号注册邮箱应用层代码流…

【注解和反射】-- 04 类加载器、运行时类的对象

反射 03 类的加载与ClassLoader 3.4 类加载器 类加载器的作用:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法中类数据的访问…

Amortized Bootstrapping of LWE:使用 BFV 打包处理

参考文献: [AP13] Alperin-Sheriff J, Peikert C. Practical bootstrapping in quasilinear time[C]//Annual Cryptology Conference. Berlin, Heidelberg: Springer Berlin Heidelberg, 2013: 1-20.[MS18] Micciancio D, Sorrell J. Ring packing and amortized F…

Flask维护者:李辉

Flask维护者:李辉, 最近看b站的flask相关,发现了这个视频:[PyCon China 2023] 濒危 Flask 扩展拯救计划 - 李辉_哔哩哔哩_bilibili 李辉讲他在维护flask之余,开发了apiflask这个依托flask的框架。GitHub - apiflask/a…

02markdown-学习笔记

一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 换行符<br>标签 写入一段测试用的正文第二段测试文本,如果要对文本进行换行可以使用<br>标签 文本修饰符 字体为斜体的修饰&#xff0c;一对星号包含 字符为粗体&#xff0c;两对星号包含 字体为…

ISP-EE(Edge Enhance)

ISP-EE(Edge Enhance) EE模块在某些ISP主控中叫做sharpness或者sharpen&#xff0c;这些名称指代的模块是同一个&#xff0c;不用再纠结。主要就是在YUV域内弥补成像过程中图像的锐度损失&#xff0c;对边缘和细节进行加强&#xff0c;从而恢复场景本应具有的自然锐度。 锐度…

三层交换与DHCP

目录 一、三层交换 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;转发原理 &#xff08;三&#xff09;ensp项目实验 二、DHCP &#xff08;一&#xff09;DHCP工作原理 1.DHCP的特点 2.工作原理 &#xff08;二&#xff09;DHCP项目实验 一、三层交…

Node.js黑马时钟案例

先上没有使用node.js之前的html部分代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title></title><style>* {margin: 0;padding: 0;}html,body {height: 100%;overflow: hidden;backgrou…

猿人学简单题分析(js逆向)

猿人学15T&#xff0c;实际带着大家分析一下。 开发者工具进行抓包&#xff0c;然后找的参数类型 由于这里的加密参数是m搜索出来的肯定是很多的&#xff0c;所以直接上XHR断点进行快速定位。 直接调用堆栈开始向上找。 控制台输出这个window.m查看这个函数的位置。 找到直接扣…

git安装和配置

git安装和配置 一、软件介绍 Git是一个免费开源的分布式版本控制系统&#xff0c;旨在快速高效地处理从小型到大型项目的所有内容。 Git易于学习&#xff0c;占地面积小&#xff0c;性能闪电般快。它以廉价的本地分支、方便的暂存区域和多个工作流等功能胜过了Subversion、C…

golang反射(reflect)虽爽,但很贵

标准库 reflect 为 Go 语言提供了运行时动态获取对象的类型和值以及动态创建对象的能力。反射可以帮助抽象和简化代码&#xff0c;提高开发效率。 但是使用反射势必会多出大量的操作指令&#xff0c;导致性能下降 案例 字段赋值方式对比 type Student struct {Name string…

1.electron之纯原生js/jquery的桌面应用程序(基础篇)

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 Electron 将 Chromium 和 Node.js 嵌入到了一个二进制文件中&#xff0c;因此它允许你仅需一个代码仓库&#xff0c;就可以撰写支持 Windows、…

灾备建设中,虚拟机异构平台恢复技术原理与应用

在如今混合云环境下&#xff0c;实现异构虚拟化恢复与迁移面临着极大挑战。不同于市面上有代理的恢复方案&#xff0c;虚拟机无代理跨平台恢复解决方案利用自主研发的转换引擎&#xff08;VMCE&#xff09;对已备份虚拟机文件进行高效的存储格式转换和配置信息转换&#xff0c;…

基于java 的经济开发区管理系统设计与实现(源码+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于java 的经济开发区管…

基于Springboot的教学信息反馈系统的设计与实现(源码+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于Springboot的教学信…

如何进行Feign的自定义配置

Feign可以支持很多的自定义配置&#xff0c;下列是部分配置信息 类型作用说明Logger.Level修改日志级别配置键&#xff1a;loggerLevel&#xff0c;包含四种不同的级别&#xff1a;NONE、BASIC、HEADERS、FULLClass<Retryer>失败重试机制配置键&#xff1a;retryer&#…

dcoker-compose一键部署EFAK —— 筑梦之路

简介 EFAK&#xff08;Eagle For Apache Kafka&#xff0c;以前称为 Kafka Eagle&#xff09;是一款由国内公司开源的Kafka集群监控系统&#xff0c;可以用来监视kafka集群的broker状态、Topic信息、IO、内存、consumer线程、偏移量等信息&#xff0c;并进行可视化图表展示。独…

stm32H库的内部FLASH读写操作与结构体数组数据写入与读取

stm32H库的内部FLASH读写操作与结构体数组数据写入与读取 1.软硬件准备2.关于STM32的Flash的一些说明3.实验结果 参考博主-STM32系列(HAL库)——内部FLASH读写实验 1.软硬件准备 软件&#xff1a;CubeMX、SSCOM&#xff08;串口调试助手&#xff09; 硬件&#xff1a;SMT32F…

如何查看KylinOS银河麒麟操作系统版本?

如何查看KylinOS银河麒麟操作系统版本? 当前银河银河麒麟高级服务器操作系统V10发行版如下&#xff1a; (Tercel) 版本是 银河麒麟 V10 SP1 版本(Sword) 版本是 银河麒麟 V10 SP2 版本(Lance) 版本是 银河麒麟 V10 SP3 版本我们可使用如下三种方式&#xff08;命令&#xff0…

【C++11特性篇】利用 { } 初始化(1)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.回顾C98标准中{}的使用二.一切皆可用…