目录
1、多线程介绍
2、线程
3、线程的调度
4、线程的生命周期
5、线程的并行与并发
6、程的同步与异步
1、多线程介绍
多线程:指的是这个程序(一个进程)运行时产生了不止一个线程,是Java语言的重要特性,大量应用于网络编程、服务器端程序的开发,最常见的UI界面底层原理、操作系统底层原理都大量使用了多线程。
多线程的应用场景:只要你想让多个事情同时运行就需要用到多线程
比如:软件中的耗时操作、所有的聊天软件、所有的服务器。我们可以流畅的点击软件或者游戏中的各种按钮,底层就是多线程的应用。UI界面的主线程绘制界面,如果有一个耗时的操作发生则启动新的线程,完全不影响主线程的工作。当这个线程工作完毕后,再更新到主界面上。
我们可以上百人、上千人、上万人同时访问某个网站,也是基于网站服务器的多线程原理。如果没有多线程,服务器处理速度会极大降低。有了多线程,我们就可以让程序同时做多件事情,提高工作效率。
多线程程序(基于一个CPU)并不能提高程序的运行速度,但能够提高程序的运行效率,让CPU使用率更高。
JUC是java.util.concurrent包的简称,在Java5.0添加,目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题!
2、线程
2.1、线程是什么?
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
一个进程中可以有多个线程,同一个进程中的多个线程共享这个进程的资源。
比如:QQ 和 Chrome 浏览器是两个进程,Chrome 进程里面有很多线程,例如 HTTP 请求线程、事件响应线程、渲染线程等等,线程的并发执行使得在浏览器中点击一个新链接从而发起 HTTP 请求时,浏览器还可以响应用户的其它事件。
2.2、为什么要引入线程?
由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O 设备等,需要较大的时空开销,限制了并发程度的进一步提高。为减少进程切换的开销,把进程作为资源分配单位和调度单位这两个属性分开处理,即进程还是作为资源分配的基本单位,但是不作为调度的基本单位(很少调度或切换),把调度执行与切换的责任交给线程,即线程成为独立调度的基本单位,它比进程更容易(更快)创建,也更容易撤销。
注意:引入线程前,进程是资源分配和独立调度的基本单位。引入线程后,进程是资源分配的基本单位,线程是独立调度的基本单位。
3、线程的调度
线程调度可以分为非抢占式和抢占式,非抢占式调度:在非抢占式系统中,一个线程一旦被选择在处理器上执行,就一直运行,直到阻塞或自愿放弃或退出;抢占式调度:抢占式系统中,一个线程被选中后,允许运行的时间长度有最大的限制,当到达这个时间后,就被迫放弃执行权,由系统来决定下一个执行的线程。
线程调度的算法有:先来先服务算法,时间片轮换算法,优先级调度算法
先来先服务算法:这是在非抢占系统中的算法,顾名思义,即谁先来先执行谁。
时间片轮换算法:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU
的时间。
优先级调度算法:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么
会随机选择一个(线程随机性)。
java使用的是抢占式调度:在Java中,线程的调度算法由操作系统负责实现,而Java虚拟机(JVM)并不直接控制线程的调度顺序。因此,具体的线程调度算法取决于底层操作系统的实现。在一般情况下,操作系统会根据线程的优先级来进行调度。优先级高的线程通常会更容易被选择执行,但并不是绝对的。操作系统可能会根据其他因素进行调整,比如时间片轮转、线程状态等。因此,并不是一定优先级越高的线程会先执行。
4、线程的生命周期
Java线程生命周期状态转换图
补充:sleep方法会让线程睡眠,睡眠时间到了之后,不会立马就执行下面的代码,因为sleep方法时间到了后,线程到了就绪队列中,需要抢占到CPU才有执行权,才会执行这个线程
线程的状态
新建状态(NEW) | ————————> | 创建线程对象 |
就绪状态(RUNNABLE) | ————————> | start方法 |
阻塞状态(BLOCKED) | ————————> | 无法获得锁对象 |
运行状态(Running) | ————————> | 线程执行 |
等待状态(WAITING) | ————————> | wait方法 |
计时等待(TIMED WAITING) | ————————> | sleep方法 |
结束状态(TERMINATED) | ————————> | 全部代码运行完毕 |
5、线程的并行与并发
并行:在同一时刻,有多个指令在多个CPU上同时执行
并发:在同一时刻,有多个指令在单个CPU上交替执行
在操作系统中,安装了多个程序,并发指的是在一段时间内宏观上有多个进程同时运行,这在单 CPU 系统中,每一时刻只能有一道进程执行,即微观上这些进程是分时的交替运行,只不过是给人的感觉是同时运行,那是因为分时交替运行的时间是非常短的。
而在多个 CPU 的系统中,则这些可以并发执行的进程便可以分配到多个处理器上(CPU),实现多任务并行执行,即利用每个处理器来处理一个可以并发执行的程序,这样多个程序便可以同时执行。目前电脑市场上说的多核 CPU,便是多核处理器,核越多,并行处理的程序越多,能大大的提高电脑运行的效率。
注意:单核处理器的计算机肯定是不能并行的处理多个任务的,只能是多个任务在单个CPU上并发运行。同理,线程也是一样的,从宏观角度上理解线程是并行运行的,但是从微观角度上分析却是串行运行的,即一个线程一个线程的去运行,当系统只有一个CPU时,线程会以某种顺序执行多个线程,这种情况就是上面介绍的线程调度。
6、程的同步与异步
同步是执行或调用一个方法时,每次都需要拿到对应的结果才会继续往后执行;异步与同步相反,它会在执行或调用一个方法后就继续往后执行,不会等待获取执行结果。二者的区别就是处理请求发出后,是否需要等待请求结果,再去继续执行其他操作。
线程安全是同步,线程不安全是异步
同步:排队执行,效率低但是安全
异步:同时执行,效率高但是数据不安全
异步情况:
同步情况:
推荐:
【操作系统】进程基础知识-CSDN博客https://blog.csdn.net/m0_65277261/article/details/136845709?spm=1001.2014.3001.5501【Java基础】IO流(三):字符流的FileReader(文件字符输入流)和 FileWriter(文件字节输出流)-CSDN博客https://blog.csdn.net/m0_65277261/article/details/136721417?spm=1001.2014.3001.5501【Java基础】IO流(二)字符集知识-CSDN博客https://blog.csdn.net/m0_65277261/article/details/136721466?spm=1001.2014.3001.5501