进程线程:进程与线程详解 2024-04-23 10:19:38 0 0 目录 一、进程 二、线程 三、进程和线程的区别 四、多线程的创建和常见方法 1、多线程的创建 2、多线程的常用方法 五、线程的安全问题 5.1、线程不安全的原因是什么? 5.2如何解决线程不安全问题 六、锁--synchronized 关键字 七、volatile 关键字的作用和用法 synchronized和volatile的区别 八、对象的等待集 8.1、wait方法 8.2、notify方法 九、多线程案例 9.1、单例模式 9.2、阻塞式队列 9.3、定时器 9.4、线程池 一、进程 进程是操作系统中一种非常重要的软件资源,当我们把一个可执行程序exe运行起来的时候,系统就会随之创建一个进程,如果这个程序结束系统会随之销毁对应的进程。 当运行exe文件时,exe文件中的很多内容都加载到内存中,通过分配资源来执行这个程序包含的指令的过程叫做进程。 进程的管理是通过先描述在组织的方法: 在Linux中每创建一个进程就会创建一个PCB这样的类的实例 创建一个进程,本质上就是在内核中先创建一个PCB对象,然后将这个对象加入到链表中。 结束一个进程的时候,本质上就是在内核中找到这个PCB对象,将他从链表中删除,并且释放该对象。 我们通过任务管理器中看到的所以的进程信息就是在内核中遍历该链表,依次读取PCB中的信息。 PCB中包含的信息: 1、进程id----进程的身份标识。 2、一组内存指针----指向该进程持有的一些重要数据在内存中的位置。 以及状态、优先级、进程的记账信息、上下文,这些模块交做调度器来实现进程模块的调度, 为了让这么多进程可以在有限的CPU上并发执行。 状态:判断是在运行还是在休眠等······ 优先级:判断这个进程是优先在CPU上执行还是放到后面······ 进程的记账信息:记录进程在CPU上执行的时间,通过时间来限制一段进程的执行······ 上下文:保存进程在CPU上执行的进度,方便下次继续执行······ 二、线程 所谓的线程其实是一种轻量级的进程 1、一个进程中包含多个线程 2、相比于进程成本更低,大部分资源是和原来的线程共享的,主要共享内存资源和打开的文件,上下文等是不能共享的。 3、每个线程都有一段自己的执行逻辑,每个线程都是一个独立的执行流。 注意:当创建出一个进程时,会随之创建一个主线程。 线程中的管理模式和进程中的一样都是先描述在组织。 一个线程和一个PCB对应,一个进程可能和多个PCB对应,在PCB中会有线程组id来对应一组线程。 进程中最多可以有多少个线程取决于: 1、CPU的个数。 2、和线程执行的任务类型也相关(CPU密集性和IO密集性)。 三、进程和线程的区别 根本区别:进程是操作系统分配资源的最小单位,线程是任务调动和执行的最小单位。 在开销方面:每个进程都有独立的代码和数据空间,程序切换会有较大的开销。线程之间共享代码和数据,每个线程都有自己独立的栈和调度器,线程之间的切换的开销较小。 所处环境:一个操作系统中可以运行多个进程,一个进程中有多个线程同时执行。 内存分配方面:系统在运行时会为每个进程分配内存,系统不会单独为每个线程分配内存。 包含关系:创建进程时系统会自动创建一个主线程由主线程完成,进程中有多线程时,由多线程共同执行完成。 四、多线程的创建和常见方法 1、多线程的创建 1、通过创建类继承Thread来调用//1、通过类直接创建 static class MyThread extends Thread{ @Override public void run() { System.out.println("qewrwerwerw"); } } public static void main(String[] args) { Thread t=new MyThread(); t.start(); } 2、通过Thread匿名内部类进行调用public static void main(String[] args) { Thread t=new Thread(){ @Override public void run() { System.out.println("wefwefwef"); } }; t.start(); } 3、通过创建类实现Runnable接口实现static class MyThread implements Runnable{ @Override public void run() { System.out.println("awetqeragearga"); } } public static void main(String[] args) { Thread t=new Thread(new MyThread()); t.start(); } 4、通过Runnable实现匿名内部类调用实现public static void main(String[] args) { Runnable runnable=new Runnable() { @Override public void run() { System.out.println("w3rqetqwetqw"); } }; Thread r=new Thread(runnable); r.start(); } 5、通过lambad表达式调用public static void main(String[] args) { Thread t=new Thread(()->System.out.println("asdasfa 收藏(0)