到底什么是线程?线程与进程有哪些区别?

上一篇文章我们讲述了什么是进程,进程的基本调度

http://t.csdn.cn/ybiwTicon-default.png?t=N176http://t.csdn.cn/ybiwT

那么本篇文章我们将了解一下什么是线程?线程与进程有哪些区别?线程应该怎么去编程?


目录

http://t.csdn.cn/ybiwThttp://t.csdn.cn/ybiwT

一、什么是线程+线程的概念

三、进程和线程的区别

 3.1 java线程和操作系统线程的关系

四、线程的创建

五、需要主要的几个地方

六、Thread类里面的一些其他方法

6.1Thread几个常见属性


一、什么是线程+线程的概念

进程,是比较“重量的”速度慢/消耗资源多的,那么创建一个进程,成本比较高;销毁一个进程,成本也比较高;调度一个进程,成本也挺高的。进程包含线程,一个进程里可以有多个线程,多个线程之间也是并发执行的。

那么线程,则是更轻量的进程(轻量级进程),一个进程中可以包含多个线程,此时这多个线程每个线程都是一个独立可以调度执行的“执行流”,同时这些进程共用一份进程的系统资源,(意味着,对于线程而言,系统资源是已经分配好了的,创建线程就省下了分配资源开销)。一个线程就是一个 "执行流". 每个线程之间都可以按照顺讯执行自己的代码. 多个线程之间 "同时" 执行着多份代码。

一个进程中的多个线程之间,共用同一份系统资源:

1.(内存空间)

2.(文件描述符表)

操作系统,真正调度的是在调度线程,而不是进程。

线程是操作系统调度运行的基本单位

进程是操作系统资源分配的基本单位

举例:滑稽老铁吃鸡

多进程吃鸡:

 多线程吃鸡:

 并不是线程越多越好,如果线程过多会影响系统的效率,如果一个线程出现了异常,可能会导致此进程中的所有线程全部崩溃!!!

二、为什么要有线程?

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

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

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

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

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

三、进程和线程的区别

1.进程包含线程

2.进程有自己独立的内存空间和文件描述符表,同一个进程中的多个线程之间,共用同一份地址空间和文件描述符表

3.进程是操作系统资源分配的基本单位,线程是操作系统调度执行的基本单位

4.进程之间具有独立性,一个进程挂了,不会影响其他的进程;同一个进程里面的线程挂了,可能会有全部的线程都挂掉

 3.1 java线程和操作系统线程的关系

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

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

四、线程的创建

方法1:继承Thread类

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

class MyThread extends Thread {
@Override
public void run() {
System.out.println("hello world");
   }
}

2) 创建 MyThread 类的实例
 

MyThread t = new MyThread();

3) 调用 start 方法启动线程
 

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

上述代码涉及俩个线程:

1.main方法所对应的线程(一个进程里面至少得有一个线程)也可以成为主线程

2.通过t.start()创建的新的线程

 

方法二:实现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的run描述线程入口

第二章写法是使用Runnable interface 来描述线程入口

没有本质区别

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

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

 

第四种:实现Runnable,使用匿名内部类,内部类(定义在类里面的类)

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

 { 放到哪里就是针对哪个类创建的匿名内部类

第五种:使用Lambda表达式,最简单直观的方法

lambda表达式的基本写法:()->{ }

public class MyThreadDemo3 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while (true){
                System.out.println("hello t"+Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }
}

 

五、需要主要的几个地方

1.sleep是Thread的静态方法,参数单位是ms,1s = 1000ms。

2.t.strat()是调用操作系统的api,创建新线程,新的线程里调用t.run,另外启动了一个执行流,新的线程来执行另一个while循环。

3.如果调用的是t.run(),而不是t.start(),那么只会有一个线程来执行,也就是只有一个循环,进入第一个死循环就出不去了,如下图:

 

 

 4.run叫入口方法,是一个特殊的方法,只是重写了父类的方法,然后这个方法就被Java自动执行到了。

当我们的代码在运行时,可以使用JDK自身带的软件去查看线程

 

 

 描述线程中的代码执行到哪里了

六、Thread类里面的一些其他方法

Thread 类是 JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的 Thread 对象与之关联。
用我们上面的例子来看,每个执行流,也需要有一个对象来描述,类似下图所示,而 Thread 类的对象就是用来描述一个线程执行流的,JVM 会将这些 Thread 对象组织起来,用于线程调度,线程管理。

方法说明
Thread()创建线程对象
Thread(Runnable target)使用 Runnable 对象创建线程对象
Thread(String name)创建线程对象,并命名
Thread(Runnable target, String name)使用 Runnable 对象创建线程对象,并命名
【了解】Thread(ThreadGroup group,
Runnable target)
线程可以被用来分组管理,分好的组即为线程组,这
个目前我们了解即可

6.1Thread几个常见属性

属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()

关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行。
isDaemon()设置为true表示是后台线程,false是前台线程,前台线程会阻止java进程结束,必须得java进程中所有得前台线程都执行完,java进程才能结束,创建的线程默认是前台的。


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

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

相关文章

HTTP详解

一,什么是HTTPHTTP(全称为“超文本传输协议”),是一种应用非常广泛的应用层协议,之前在《初识网络原理》的博客(初识网络原理_徐憨憨!的博客-CSDN博客)中,有详细讲解过TCP/IP五层模型,其中应用层描述了数据…

算法---完成任务的最少工作时间段

题目: 你被安排了 n 个任务。任务需要花费的时间用长度为 n 的整数数组 tasks 表示,第 i 个任务需要花费 tasks[i] 小时完成。一个 工作时间段 中,你可以 至多 连续工作 sessionTime 个小时,然后休息一会儿。 你需要按照如下条件…

即时通讯系列-N-客户端如何在推拉结合的模式下保证消息的可靠性展示

结论先行 原则: server拉取的消息一定是连续的原则: 端侧记录的消息的连续段有两个作用: 1. 记录消息的连续性, 即起始中间没有断层, 2. 消息连续, 同时意味着消息是最新的,消息不是过期的。同…

CKA最新考试费用是多少?考试内容是什么?

CKA认证考试是由Linux基金会和云原生计算基金会(CNCF)创建的,以促进Kubernetes生态系统的持续发展。该考试是一种远程在线、有监考、基于实操的认证考试,需要在运行Kubernetes的命令行中解决多个任务。CKA认证考试是专为Kubernetes管理员、云管理员和其他…

YOLOv8初体验:检测、跟踪、模型部署

安装 YOLOv8有两种安装方式,一种是直接用pip命令安装: pip install ultralytics另外一种是通过源码安装: git clone https://github.com/ultralytics/ultralytics cd ultralytics pip install -e .[dev]安装完成后就可以通过yolo命令在命令…

Yolov8详解与实战

文章目录摘要模型详解C2F模块Losshead部分模型实战训练COCO数据集下载数据集COCO转yolo格式数据集(适用V4,V5,V6,V7,V8)配置yolov8环境训练测试训练自定义数据集Labelme数据集摘要 YOLOv8 是 ultralytics …

Git规范

Commit 规范 常见的开源社区 commit message 规范: 比如 Angular 规范: 语义化:commit message 被归为有意义的类型用来说明本次 commit 的类型。 规范化:commit message 遵循预先定义好的规范,比如格式固定、都属…

GIS(地理信息系统/地理信息科学)职称评审三:中科院和人社部职称评审结果公示对比

目录1.前言2.中科院3.人社部3.1 初级、中级3.2 高级、正高级3.3 公示时间4. 证书5. 程序员要不要评职称?6.总结1.前言 我们在前两篇已经讲过了GIS(地理信息系统/地理信息科学)怎么评职称?以及中科院和人社部职称评审所需材料内容对…

Qss样式表语法

QSS样式表语法 更多精彩内容👉个人内容分类汇总 👈👉QSS样式学习 👈文章目录QSS样式表语法[toc]概述一、样式规则二、选择器类型三、子控件四、伪状态五、样式表冲突解决六、级联七、继承八、命名空间中的控件概述 Qt样式表的概念…

2023年了,还是没学会内卷....

先做个自我介绍:我,普本,通信工程专业,现在飞猪干软件测试,工作时长两年半。 回望疫情纪元,正好是实习 毕业这三年。要说倒霉也是真倒霉,互联网浪潮第三波尾巴也没抓住,狗屁造富神…

软件缺陷详解

软件缺陷报告 知识点 软件缺陷的定义缺陷产生的原因如何编写缺陷报告缺陷报告的书写准则 简介 软件测试的目的是为了发现尽可能多的缺陷,这里的缺陷是一种泛称,他可以指功能的错误,也可以指性能低下,或者易用性差等。执行软件…

深度学习必备知识——模型数据集Yolo与Voc格式文件相互转化

在深度学习中,第一步要做的往往就是处理数据集,尤其是学习百度飞桨PaddlePaddle的小伙伴,数据集经常要用Voc格式的,比如性能突出的ppyolo等模型。所以学会数据集转化的本领是十分必要的。这篇博客就带你一起进行Yolo与Voc格式的相互转化&…

力扣-超过经理收入的员工

大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:181. 超过经理收入的员工二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其…

Android之屏幕适配方案

在说明适配方案之前,我们需要对如下几个概念有所了解:屏幕尺寸,屏幕分辨率,屏幕像素密度。 屏幕尺寸 屏幕尺寸指屏幕的对角线的物理长度,单位是英寸,1英寸2.54厘米。 比如常见的屏幕尺寸:5.0、5…

组件库项目搭建

创建项目 使用pnpm create vite@latest 命令创建项目。 输入项目名,选择对应参数。 删除不需要的文件 添加pnpm-workspace.yaml 在项目根目录下创建一个pnpm-workspace.yaml文件,配置如下: packages:- demo # 存放组件示例代码- packages # packages 目录下都是组件包…

【pygame游戏】Python实现蔡徐坤大战篮球游戏【附源码】

前言 话说在前面,我不是小黑子~😏 本文章纯属技术交流~娱乐 前几天我获得了一个坤坤打篮球的游戏,也给大家分享一下吧~ 好吧,其实并不是这样的游戏,往下慢慢看吧。 准备工作 开发环境 Python版本:3.7.8 …

右值和右值引用(C++11新特性)

文章目录右值VS左值右值引用VS左值引用定义move函数左值引用&&右值引用 与 函数重载模板完美转发左值引用的意义移动构造&&移动赋值默认移动构造&&赋值右值VS左值 关于什么是右值什么是左值,我们是这样判断的: 右值&#xff1…

VSCode使用技巧,代码编写效率提升2倍以上!

VSCode是一款开源免费的跨平台文本编辑器,它的可扩展性和丰富的功能使得它成为了许多程序员的首选编辑器。在本文中,我将分享一些VSCode的使用技巧,帮助您更高效地使用它。 1. 插件 VSCode具有非常丰富的插件生态系统,通过安装插…

Python直接复制已有的venv虚拟环境以创建新的虚拟环境

Python venv创建的虚拟环境复制到其他路径,如何断开与原始虚拟环境的连接,成为一个全新的虚拟环境,且两个虚拟环境之间的更新互不影响?1.软件环境⚙️2.问题描述🔍3.解决方法🐡3.1.方法1:先复制…

用Python Flask为女朋友做一个简单的网站(附可运行的源码)

🌟所属专栏:献给榕榕🐔作者简介:rchjr——五带信管菜只因一枚😮前言:该专栏系为女友准备的,里面会不定时发一些讨好她的技术作品,感兴趣的小伙伴可以关注一下~👉文章简介…