进程
进程是程序执行的一次过程,是系统运行程序的基本单位,进程是动态的.系统运行一个程序就代表一个进程生命周期从创建,运行到消亡的过程。
在java中,启动main函数就代表启动了一个jvm的进行.main函数所在的线程就是这个进程中的一个线程,也称主线程.
线程
线程和进程相似,但是线程是比进程更小的执行单元.一个进程在执行的过程中会产生多个线程.与线程不同的是同类的多个线程之间会共享进行的堆空间和方法区中的资源,并且每个线程都有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,或是在各个线程之间进行上下文切换时,负担是要比进程小得多的,因此线程也被称为轻量级进程.
线程与进程的关系,区别及优缺点
一个进程可以有多个线程,多个线程共享进程的堆空间和方法区(jdk8以后被称为元空间)资源,但是每个线程都有自己的程序计数器,虚拟机栈和本地方法栈.
线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。
程序计数器为什么是私有的
程序计数器的主要作用有两个:
1. 字节码是通过程序计数器来读取指令,从而实现代码的流程控制的.
2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道上次线程运行到哪里了.
因此程序技术器私有主要是为了线程切换后能恢复到正确的位置
虚拟机栈和本地方法栈为什么是私有的?
- 虚拟机栈: 每个 Java 方法在执行之前会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
- 本地方法栈: 和虚拟机栈所发挥的作用非常相似,区别是:虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。
所以,为了保证线程中的局部变量不被别的线程访问到,虚拟机栈和本地方法栈是线程私有的。
并发与并行的区别
- 并发:两个及两个以上的作业在同一 时间段 内执行。
- 并行:两个及两个以上的作业在同一 时刻 执行
同步和异步的区别
- 同步:发出一个调用之后,在没有得到结果之前, 该调用就不可以返回,一直等待。
- 异步:调用在发出之后,不用等待返回结果,该调用直接返回。
使用多线程可能带来的问题
并发编程的目的就是为了能提高程序的执行效率提高程序运行速度,但是并发编程并不总是能提高程序运行速度的,而且并发编程可能会遇到很多问题,比如:内存泄漏、死锁、线程不安全等等。
如何理解线程安全和不安全
线程安全和不安全是在多线程环境下对于同一份数据的访问是否能够保证其正确性和一致性的描述。
- 线程安全指的是在多线程环境下,对于同一份数据,不管有多少个线程同时访问,都能保证这份数据的正确性和一致性。
- 线程不安全则表示在多线程环境下,对于同一份数据,多个线程同时访问时可能会导致数据混乱、错误或者丢失。
线程的生命周期和状态
- NEW: 初始状态,线程被创建出来但没有被调用
start()
。 - RUNNABLE: 运行状态,线程被调用了
start()
等待运行的状态。 - BLOCKED:阻塞状态,需要等待锁释放。
- WAITING:等待状态,表示该线程需要等待其他线程做出一些特定动作(通知或中断)。
- TIME_WAITING:超时等待状态,可以在指定的时间后自行返回而不是像 WAITING 那样一直等待。
- TERMINATED:终止状态,表示该线程已经运行完毕。
什么是线程上下文切换
线程在执行过程中会有自己的运行条件和状态(也称上下文)。
- 主动让出 CPU,比如调用了
sleep()
,wait()
等。 - 时间片用完,因为操作系统要防止一个线程或者进程长时间占用 CPU 导致其他线程或者进程饿死。
- 调用了阻塞类型的系统中断,比如请求 IO,线程被阻塞。
- 被终止或结束运行
这其中前三种都会发生线程切换,线程切换意味着需要保存当前线程的上下文,留待线程下次占用 CPU 的时候恢复现场。并加载下一个将要占用 CPU 的线程上下文。这就是所谓的 上下文切换。