了解计算机的进程与线程
-
何为进程?
进程是程序的一次执行过程,是系统运行程序的基本单位,系统会为进程发配独立的【内存资源】!
进程是动态的,它有自己独立的生命周期,它会在启动程序时产生,运行程序时存在,关闭程序时消亡 -
何为线程?
线程是由进程创建的,是进程的一个实体,是具体干活的,
一个进程可能有多个线程。线程不独立分配内存,而是共享进程的内存资源,线程可以共享cpu的计算资源
现在,进程更强调【内存资源的分配】,而线程更强调【计算资源的分配】。
多个线程共享进程的堆和方法区资源,
但每个线程有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,
或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。 -
线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。
JVM线程
Java 线程基于系统原生线程(Native Threads)实现,
也就是说 JVM 直接使用操作系统原生的内核级线程内核线程来实现Java 线程,
Java 线程由操作系统内核进行线程的调度和管理
内核线程:由操作系统内核管理和调度的线程,运行在内核空间
用户态和内核态
用户线程执行的过程我们称之为【用户态】,内核调度的状态称之为【内核态】
一个线程运行时产生的数据我们称之为【上下文】
线程的每次切换都需要进行用户态到内核态的来回切换,同时伴随着上下文的切换
是一个比较消耗资源的操作
**在多线程开发过程中!我们要尽量避免频繁的从用户态——>内核态之前的切换(消耗资源)!!!**
上下文切换
线程在执行过程中会有自己的运行条件和状态(也称上下文),比如程序计数器,栈信息等。
当出现如下情况的时候,线程会从占用 CPU 状态中退出。
1.主动让出 CPU,比如调用了 sleep(), wait() 等。
2.时间片用完,因为操作系统要防止一个线程或者进程长时间占用 CPU 导致其他线程或者进程饿死
3.调用了阻塞类型的系统中断,比如请求 IO,线程被阻塞
4.被终止或结束运行
前三种都会发生线程切换,线程切换意味着需要保存当前线程的上下文,留待线程下次占用 CPU 的时候恢复现场。并加载下一个将要占用 CPU 的线程上下文。这就是所谓的 上下文切换
上下文切换是现代操作系统的基本功能,因其每次需要保存信息恢复信息,这将会占用 CPU,内存等系统资源进行处理,也就意味着效率会有一定损耗,如果频繁切换就会造成整体效率低下
并发和并行
"并发"和"并行"是计算机科学中两个相关但不同的概念,主要关注任务的执行方式
- 并发 (Concurrency):
定义: 并发指的是两个或多个任务在同一时间段内发生。它不一定要求这些任务同时进行,可以是任务之间交替 执行,通过操作系统的任务调度在短时间内完成多个任务的切换。
关注点: 并发更注重多个任务之间的交替执行,提高整体系统的效率,尽管在任意时刻只有一个任务在执行。
- 并行 (Parallelism):
定义: 并行指的是两个或多个任务在同一时刻执行,要求同时发生。这通常需要硬件支持,例如多核处理器或分布式系统。
关注点: 并行更注重同时执行多个任务,每个任务有自己的处理单元,真正的同时性。
- 总结
并发是多个任务在时间上有重叠,但不一定同时执行。
并行是多个任务在同一时刻执行。
并发强调任务的交替执行,通过任务切换来提高整体效率。
并行强调同时执行多个任务,实现真正的同时性,通常需要硬件支持。
在实际应用中,可以同时存在并发和并行。例如,一个多核处理器上的任务可以通过并行来执行,而这些任务之间可能也存在一定的并发性
最关键的点是:是否是 同时 执行
同步和异步的区别
"同步"和"异步"是指任务执行的两种不同方式。
同步(Synchronous):
发出一个调用之后,在没有得到结果之前, 该调用就不可以返回,一直等待
同步任务是按照顺序执行的,一个任务的执行会阻塞后续任务的执行。
在同步模型中,当一个任务开始执行时,程序会等待它完成,然后再执行下一个任务。
同步通常用于简单的、顺序执行的任务,确保任务按照预定的顺序依次执行。
异步(Asynchronous):
调用在发出之后,不用等待返回结果,该调用直接返回。
异步任务是不按照顺序执行的,一个任务的开始并不等待它的完成,而是直接开始执行下一个任务。
在异步模型中,任务的执行不会阻塞程序的流程,而是通过回调、事件或者异步操作来处理任务的结果。
异步通常用于处理需要等待的、耗时的任务,以充分利用系统资源,不阻塞其他任务的执行。
同步:
优点:简单,易于理解。
缺点:可能会导致等待时间,降低程序的执行效率。
异步:
优点:提高了程序的执行效率,充分利用系统资源。
缺点:代码相对复杂,可能引入回调地狱(Callback Hell)等问题。
在现代应用程序中,异步通常用于处理网络请求、文件读写、用户输入等可能会引起等待的场景,以确保程序的流畅性和响应性。
多线程使用场景
多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销,提高进程利用多核 CPU 的能力
利用好多线程机制可以大大提高系统整体的并发能力以及性能(执行效率提高程序运行速度)
对于现代系统来说多线程并发编程正是开发高并发系统的基础
- 可能带来的问题
比如:内存泄漏、死锁、线程不安全等等
如何理解线程安全和不安全?
线程安全和不安全是在多线程环境下对于同一份数据的访问是否能够保证其正确性和一致性的描述
线程安全指的是在多线程环境下,对于同一份数据,不管有多少个线程同时访问,都能保证这份数据的正确性和一致性。线程不安全则表示在多线程环境下,对于同一份数据,多个线程同时访问时可能会导致数据混乱、错误或者丢失。