什么是进程
进程的定义:进程是正在运行的程序实体,并且包括这个运行的程序中占据的所有系统资源,比如说CPU(寄存器),IO,内存,网络资源等。
但这些定义十分抽象,可以打开任务管理器来查看进程
操作系统中的一个exe程序就可以认为是进程
什么是线程
线程的定义:线程是指进程中的一个执行流程,一个进程中可以运行多个线程。
线程可以理解为进程执行中的一些子任务,这些线程各自执行一些任务,才构成了一个完整的exe程序(进程).
因此 先有进程,后有线程,进程中可以创建多个线程,至少有一个线程,但不能没有线程
进程负责向操作系统申请资源,在一个进程中,多个线程共享相同的内存和文件资源.
上下文切换
即使是单核处理器也支持多线程执行代码,进行并发编程时,CPU会不断地切换线程执行.但是切换的时间很快,因此我们是感知不到线程是切换的
CPU通过时间分配算法来循环执行任务,当执行一段时间后切换到另一个任务.在切换之前,需要保存上一个任务执行的状态,以便下次切换回来的时候,再加载这个任务的状态,可以接着上次切换前的状态继续往下运行,任务从保存到再加载的过程就是一次上下文切换
减少上下文的方法有:无锁并发编程 CAS算法 使用最少线程和使用协程
多线程一定比串行执行快吗
通过以下简单的示例即可验证:
public class Example3 {
private static final long count = 10000001;
public static void main(String[] args) {
concurrency();
serial();
}
private static void concurrency(){
long start = System.currentTimeMillis();// 记录程序开始运行的时间
Thread thread = new Thread(()->{
int a = 0;
for (long i = 0; i < count; i++) {
a++;
}
});
thread.start();
int b = 0;
for (long i = 0; i < count; i++) {
b++;
}
try {
thread.join();// 等待线程结束
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
long end = System.currentTimeMillis();// 记录结束时间
System.out.println(end-start);
}
private static void serial(){
long start = System.currentTimeMillis();
int a = 0;
for (long i = 0; i < count; i++) {
a++;
}
int b = 0;
for (long i = 0; i < count; i++) {
b++;
}
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
通过改变count的值,来观察它们运行时间的差距即可
因此很容易得出结论: 多线程不一定比串行执行快 只有当数据量足够多时,多线程才比串行执行快
这是因为线程在创建以及进行上下文交换时有一定的开销.
进程与线程的区别与联系
在启动线程时,只有第一个线程的开销比较大,后面的开销就很小了
在不支持线程的操作系统中,进程既是资源分配的基本单位,也是调度的基本单位;在拥有线程的操作系统中,线程是调度的基本单位,而进程是资源分配的基本单位。
进程虽然是独立的,但它们之间可以相互通信
线程在进程中,属于子集关系
虽然线程很轻,但是线程之间的上下文切换时间成本很高