目录:
-
前言
-
1 程序、进程和线程
-
2 从 JVM 角度看进程和线程之间的关系
-
- 2.1 程序计数器为什么是私有的
-
2.2 虚拟机栈和本地方法栈为什么是私有的
-
3 多线程的概念
-
- 3.1 并发和并行的区别
-
3.2 上下文切换
-
3.3 为什么使用多线程
-
3.4 线程的生命周期和状态
-
3.5 什么是线程死锁?如何避免死锁?
-
4 多线程的使用
-
- 4.1 多线程的实现方法
-
4.2 sleep() ⽅法和 wait() 方法的区别
-
4.3 sleep() 方法和 yield() 方法的区别
-
4.4 join() 方法的作用
-
4.5 Thread 调用 start() 方法和调用 run() 方法的区别
-
4.6 synchronized 关键字
-
4.7 synchronized 和 Lock 的区别
-
4.8 synchronized 关键字和 volatile 关键字的区别
-
4.9 为什么要弄⼀个 CPU 高速缓存
-
5 线程池
-
- 5.1 为什么使用线程池
-
5.2 线程池的原理
-
5.3 线程池的代码实现
-
5.4 线程池的核心属性
-
5.5 线程池的拒绝策略(饱和策略)
-
5.6 一些面试问题
-
6 生产者消费者模式
=============================================================================
-
程序:程序是存储在磁盘或者其它的数据存储设备中的含有指令和数据的文件,也就是说程序是静态的代码;
-
进程:进程是程序的一次执行过程,系统运行一个程序即是一个进程从创建到运行再到消亡的过程;
-
线程:线程是一个比进程更小的执行单元,一个进程在执行的过程中可以产生多个线程。
(总结:进程就是程序的一次执行过程,线程则是比进程更小的执行单元,一个进程可以产生多个线程。)
线程和进程最大的不同在于各进程基本上是独立的,而同类的多个线程共享进程的堆和方法区资源,不过每个线程有自己的程序计数器、虚拟机栈和本地⽅法栈。同时,系统产⽣⼀个线程,或是在各个线程之间作切换⼯作时,负担要⽐进程⼩得多,也正因为如此,线程也被称为轻量级进程。
========================================================================================
Java 的内存区域如下:
从上图可以看出:⼀个进程中可以有多个线程,多个线程共享进程的堆和⽅法区 (JDK1.8 之后叫做元空间)资源,但是每个线程有⾃⼰的程序计数器、虚拟机栈和本地⽅法栈。
程序计数器有以下两个作用:
-
字节码解释器通过改变程序计数器来依次读取指令,从⽽实现代码的流程控制,如:顺序执⾏、选择、循环、异常处理;
-
在多线程的情况下,程序计数器⽤于记录当前线程执⾏的位置,从⽽当线程被切换回来的时候能够知道该线程上次运⾏到哪⼉了。
所以,程序计数器私有主要是为了线程切换后能恢复到正确的执行位置。
-
虚拟机栈: 每个 Java ⽅法在执⾏的同时会创建⼀个栈帧⽤于存储局部变量表、操作数栈、常量池引⽤等信息。每一 Java 方法从调⽤⾄执⾏完成的过程,就对应着⼀个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
-
本地⽅法栈: 和虚拟机栈所发挥的作⽤⾮常相似,区别是: 虚拟机栈为虚拟机执⾏ Java ⽅法 (也就是字