目录
一、引用线程的原因
二、线程的概念
三、进程和线程的区别
四、多线程编程
一、引用线程的原因
多任务操作系统,希望系统能同时运行多个任务。所以会涉及到进程,需要对进程进行管理、调度等。
而单任务操作系统,就完全不涉及到进程,也不需要管理、调度了。
而进程,就是解决并发编程的这样问题,事实上,进程也能解决大部分并发编程的问题(Java不提倡多进程编程)。但有些情况就很乏力了,如下:
网站 / Web开发,是一种服务器程序,我们知道,一个网站服务器在同一时刻,会受到很多请求,针对这些请求,会创建进程,一个请求创建一个进程,创建完一个进程,又要销毁这个进程,这意味着这个网站服务器要频繁的创建和释放资源,这个操作开销是比较大的,
原因:
我们知道,进程是资源(CPU,硬盘,内存,网络带宽)分配的基本单位,而一个进程,刚启动的时候,首当其冲的就是申请内存资源,因为进程需要把依赖的代码 / 数据,从磁盘加载到内存中。
而从系统分配一个内存,并非是件容易的事,一般来说,申请内存的时候需要指定一个大小,系统内部就要把各自大小的空闲内存,通过一定的数据结构,给组织起来,实际申请的时候,就需要去这样的空间中进行查找,找到一个大小合适的空闲内存,进行分配。
结论:进程在创建和销毁的时候,开销比较大,主要体现在申请和释放资源上。
这时,我们就引入线程,来解决开销比较大的问题。
二、线程的概念
线程也可以理解成“轻量级进程”,基于进程做的一些改进和调整,使其变得开销(资源的申请和释放)不那么大。
因为进程的独立性,一个进程在内存中申请一块资源时,那个块资源只能让那个进程使用,其他的进程不能使用。而一个线程在内存中申请了一块资源,其他不同的线程也可以使用这块资源,这样就避免了多次的资源申请和释放。PCB可以表示进程,也可以表示线程。
进程在内存中的使用范围,如图
PCB有个属性,是内存指针
多线程的PCB,也有内存指针,但可以指的是同一块内存空间,以及进程有的pid、状态、
上下文、优先级等,线程也有。
三、进程和线程的区别
1、进程包含线程,进程可以理解成多个线程的组合,这些线程称为线程组。
关系图如下:
2、进程扮演的角色是申请内存空间,而线程扮演的角色是调度数据 / 执行代码。
3、1个进程至少有1个线程,每个进程有自己的资源空间,而进程里的线程共用这块资源空间。
4、进程和进程之间不会相互影响,但是进程中的某个线程出问题了,可能会影响到这个进程中的其他线程,导致这个进程也出问题。
5、同一个进程中的线程之间,可能会相互干扰,引起线程安全问题。
6、线程不是越多越好,应该要合适,如果线程太多了,调度开销可能非常明显。
四、多线程编程
一个简单的线程创建,代码如下:
class MyThread extends Thread {
@Override
public void run() {
//run方法是该线程的入口方法
System.out.println("Hello World");
}
}
public class SystemCode {
public static void main(String[] args) {
//2、根据刚才的类,创建一个实例
Thread t = new MyThread();
//3、调用Thread的start方法,才会真正调用系统的api,在系统内核中创建线程
t.start();
}
}
执行结果: