1.进程、线程和程序
多线程和多进程的应用场景:
多进程:
1.chrome浏览器就使用的多进程的方式,一个网页崩溃不会影响到其他进程。
2.几乎所有的web server服务器都有多个进程,至少一个守护进程和一个工作进程。
多线程:
1.有IO交互的应用,都会有一个线程是处理IO操作的。
2.进程之间进行数据共享时,要修改数据。
3.桌面应用响应用户操作和后台程序处理
线程和进程的区别:
- 进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位
- 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
- 同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的
程代码编写更加困难,可能出现线程安全的问题
进程:进程是一个动态的实体,有他自己的地址空间,程序是没有生命的实体,当处理器执行程序时,他就变为一个活动的实体也就是进程。
线程是一个进程中独立运行的子任务
线程:一个进程可以有多个线程,同一个进程的线程可以共享该线程的堆区、方法区资源,但每个线程有自己的程序员计数器、虚拟机栈、本地方法栈。比进程更轻量级,创建或销毁一个线程比创建或销毁一个进程容易的多。
协程:协程是一种轻量级的线程,协程的切换完全由用户控制,它不用转换到内核态,所以它上下文切换非常快,
线程间的通信主要靠上下文切换和共享内存。
进程间的通信:管道、有名管道、套接字、共享内存、信号量、信号、消息队列。
程序和进程;
程序是静态的实体,进程是动态的实体,进程是程序的一部分。
程序计数器:
简单来说就是指示线程运行到哪一行,字节码指示器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令。还有在线程切回时获取该线程上次执行到那.
java虚拟机栈:
主要有局部变量表、常量池引用、操作数栈,中主要存放了编译器可知的各种基本数据类型和对象的引用。
出现的两种异常:
StackOverFlowError:请求超出了虚拟机栈的最大深度;
OutOfMemoryError:当请求用完虚拟机栈的内存时;
本地方法栈:和虚拟机栈大致相同,只不过虚拟机栈是为虚拟机执行的Java方法服务的,而本地方法栈是为虚拟机使用到的Native方法服务。
虚拟机栈和本地方法栈为什么是线程私有的?
为了保证线程中的局部变量不被其他线程访问到
堆和方法区
堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象,方法区主要用于存放以被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
2、为什么使用多线程
- 降低资源消耗:通过重用已经创建的线程来降低线程创建和销毁的消耗
- 提高响应速度:任务到达时不需要等待线程创建就可以立即执行
- 提高线程的可管理性:线程池可以统一管理、分配、调优和监控
多线程会带来的问题:
内存泄漏、死锁、线程不安全等
线程的生命周期:
NEW 初始态
RUNNABLE 运行态
- READY 就绪态
- RUNNING 运行中
BOLCKED 阻塞态
WAITING 等待态
TIME_WAITING 超时等待
TERMINATED 终止态
上下文切换:
当一个线程在执行完CPU时间片时,就会处于就绪态,让其他线程执行,这个过程就时上下文切换
死锁
多个线程被阻塞,他们中的一个或全部都在等待一个资源被释放,由于线程被无限期阻塞,所以程序不可能正常终止。
package ThreadDemo;
public class DeadLockDemo {
private static Object object1 = new Object();
private static Object object2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (object1){
System.out.println(Thread.currentThread()+"get object1");
try