[JavaEE] 线程与进程的区别详解

news/2024/12/2 21:52:08/


 专栏简介: JavaEE从入门到进阶

题目来源: leetcode,牛客,剑指offer.

创作目标: 记录学习JavaEE学习历程

希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长.

学历代表过去,能力代表现在,学习能力代表未来! 


目录

认识线程(Thread)

1. 线程是什么?

2. 为什么要有线程?

3. 线程和进程的区别?

4. Java线程和操作系统线程的关系 

5. 创建多线程

6. 使用JConsole 查看线程状态


认识线程(Thread)

1. 线程是什么?

一个线程就是一个执行流 , 每个线程都可以按照自己的顺序来执行代码 , 多个线程同时执行着多份代码.

例如: 一家公司的会计张三去银行办理业务 , 业务范畴很广 , 有财务转账 , 社保缴纳 , 员工福利发放. 如果只有张三一个会计 , 就会耗费很长的时间. 为了节省时间 , 公司张三又叫来了李四和王五 , 三个人分别排队叫号 , 自此就有三个执行流共同完成任务 , 但本质上他们还是办理同一家公司的业务 . 此时我们就把这种情况称为多线程 , 将一个大任务分成多个小任务 , 交给不同执行流分别排队执行.其中李四和王五是张三叫来的 , 那么张三就是主线程.(Main Thread).


2. 为什么要有线程?

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

  • 单核CPU的发展遇到了瓶颈 , 想要提高算力 , 需要使用多核CPU. 而并发编程恰好能更充分的利用多核CPU资源.
  • 有些任务常见需要等待"IO" , 为了让程序在等待"IO"的同时做一些其他工作 , 也需要用到并发编程.

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

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

 Tips:虽然线程比进程更轻量 , 但人们并不满足于此 , 于是有了"线程池"(Thread Pool)和协程(Coroutine)


3. 线程和进程的区别?

维度多进程多线程总结
数据共享 , 同步

数据是分开的 , 共享复杂;

同步简单.

多线程共享进程数据 , 共享简单;

同步复杂

各有优势
内存, CPU

占用内存多 , CPU利用率低

占用内存少 , CPU利用率高

线程占优
创建销毁, 切换创建销毁 , 切换复杂 , 速度慢创建销毁 , 切换简单 , 速度快线程占优
编程调试编程简单 , 调试简单编程复杂 , 调试复杂进程占优
可靠性进程间不会相互影响

一个线程挂掉将导致

整个进程挂掉

进程占优
分布式

适用于多核 , 多机分布;

如果一台机器不够 , 

扩展到多台机器比较简单

适用于多核分布线程占优
  • 进程包含线程 , 每个进程中至少有一个线程存在 , 即主线程.
  • 进程和进程之间不共享内存空间 , 同一个进程的多个线程之间共用进程的同一份资源.(内存和文件描述符表)
  • 进程是系统分配资源的最小单位 , 线程是系统调度的最小单位.

还是之前的例子 , 每个来银行办理业务的客户相当于一个进程 , 他们的票据肯定不同 , 否则银行卡中的钱就被别人取走了 , 而张三李四王五虽然是三个不同的执行流 , 但办理的都是同一家公司的业务 , 所以票据是共享的 , 这就是多线程和多进程最大的区别.


4. Java线程和操作系统线程的关系 

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

Java标准库中的Thread类可以看做是对操作系统提供的线程API做进一步的抽象和封装.


5. 创建多线程

1) 继承Thread重写run()

t.start 真正创建了一个线程 , 线程是独立的执行流. run() 只是描述了线程要执行的任务是什么 , 

class MyThread extends Thread{@Overridepublic void run(){System.out.println("Hello thread");}
}
public static void main(String[] args) {Thread t = new MyThread();t.start();//start 创建了一个新的线程 , 新的线程负责执行t.run().System.out.println("Hello main");}

2) 实现Runnable()

将任务与线程区分开来,让线程和任务之间解耦合.(低耦合) 好处是如果后期要改成多进程 , 或者线程池 , 或者协程.....此时代码改动比较小.

 class MyRunnable implements Runnable {//Runnable 作用 , 描述一个"要执行的任务" , run 方法就是任务执行的细节.@Overridepublic void run() {System.out.println("Hello Thread");}
}
public static void main(String[] args) {//描述一个任务Runnable runnable = new MyRunnable();//把任务交给线程来执行Thread t = new Thread(runnable);t.start();}

3) 使用匿名内部类

new Thread 创建了 Thread 类的子类 , 因为子类没有名字叫匿名匿名内部类 , 并且让 t 引用指向该实例.

public static void main(String[] args) {Thread t = new Thread(){@Overridepublic void run(){System.out.println("Hello thread");}};t.start();}

4) 使用匿名内部类实现Runnable()

该方法与第二种方法本质相同. 只不过把实现 Runnable 的任务交给匿名内部类.最后将匿名内部类的实例交给 Thread 类的构造方法.

public static void main4(String[] args) {Thread t = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Hello thread");}});t.start();}

5)j简便写法 Lambda表达式

直接把 lambda 传给Thread 构造方法.

 public static void main5(String[] args) {Thread t = new Thread(()->{System.out.println("Hello world");});t.start();}

6. 使用JConsole 查看线程状态

JConsole 是 jdk 自带的一种基于JMX的可视化监控 , 管理工具.主要用于查看线程的状态.

打开 jdk 进入bin目录 , 找到 jconsole.

jconsole只能查看正在运行的线程状态 , 我们先在本地 ideal 运行一个多线程的Java程序.这时打开jconsole 找到我们创建的Java程序 , 点击连接.

 忽略不安全的连接提示 , 进入线程专栏.

 此时我们可以看到多个线程 , 其中main是主线程 , Thread-0是我们创建的另一个线程.其余线程都是JVM自带的.

 选择指定的线程后 , 在堆栈跟踪中就可以查看到线程调用栈具体的执行细节. 这对于后期多线程程序的调试工作有很大的用处.


http://www.ppmy.cn/news/6712.html

相关文章

C#项目实战——【实例】企业人事管理系统(一):1、系统分析;2、系统设计;3、系统运行环境;

学习《C#从入门到精通》,边学边练记录实现过程。 1、系统分析 1.1、需求分析 基于其他企业人事管理软件的不足,要求能够制作一个可以方便、快捷地对职工信息进行添加、修改、删除的操作,并且可以在数据库中存储相应职工的照片。为了能够更…

【C++初阶】list的模拟实现

文章目录list的介绍list的模拟实现成员变量Member functionsconstructordestructoroperatorIterators正向迭代器反向迭代器beginendrbeginrendModifierspush_frontpop_frontpush_backpop_backinserteraseclear完整版代码list.hreverse_iterator.htest.cpplist的介绍 list是STL…

力扣:两数之和

原题链接:https://leetcode.cn/problems/two-sum/description/ 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&…

numpy数组,numpy索引,numpy中nan和常用方法

一:【numpy数组】 1.1为什么要学习numpy 1.快速 2.方便 3.科学计算的基础库 1.2什么是numpy 一个python中做科学计算的基础库,重在数值计算,也是大部分python科学计算库的基础库,多用于在大型,多维数组上执行数组运…

如何定制化Spring Boot Starter,这次我终于学会了

文章目录什么是Spring Boot Starter实现步骤启动器自动配置包总结自定义Starter的实现逻辑Spring Boot Starter官网描述:Spring Boot Starter官方介绍 什么是Spring Boot Starter Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包&…

shell脚本四剑客之awk详解

文章目录awk的介绍awk能够干什么awk的格式工作原理:记录和域内建变量的用法1. FS2. OFS3.RS4. ORS5. NF6. NRBEGIN 和END语句块常见案例1. 使用NR行号提取ip2. 打印UID小于10的账号名称和UID信息3. 数学运算4. AWK打印硬盘设备名称,默认以空格为分割&…

买不到的数目(蓝桥杯C/C++A组真题详解)

题目详细: 题目思路: 对于这个题有一个定理 如果 a,b 均是正整数且互质,那么由 axby,x≥0,y≥0 不能凑出的最大数是 : a*b-a-b 具体的证明过程这里就不赘述 感兴趣的同学可以自行查找 这里就提供一种思…

Python常见问题整理

Python常见问题整理   日常使用python时,经常遇到的各种解决不了、头疼的问题,都可以记录到这里,大家群策群力,积极补充~  序号问题标题问题现象原因解决方法参考文章添加人报错截图0ModuleNotFoundError代码运行报错ModuleNot…