1.概述
①TPS:每秒处理事务
②QPS:
2.Java内存模型
①JMM用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现Java程序在各种平台下都能达到一致的内存访问效果
3.主存与工作内存
①JMM主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量的底层细节
②JMM规定了所有的变量都存储在主内存中
③每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主存中的变量
④不同线程之间也无法直接访问对方工作内存中的变量
⑤线程间变量值的传递均需要通过主内存来完成
4.内存间交互操作
①lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态
②unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量可以被其他线程锁定
③read(读):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load操作
④load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中
⑤use(使用):作用于工作内存的变量,它把工作内存中的一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用到变量的值的字节码指令时将会执行这个操作
⑥assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的赋值给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作
⑦store(存储):作用于工作内存变量,他爸工作内存中一个变量的值传送到主内存中,以便随后的write操作
⑧write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中
5.对于volatile型变量的特殊规则
①保证此变量对所有线程的可见性
②禁止指令重排序优化
6.线程的实现
①线程是比进程更加轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和执行调度分开,各个线程既可以共享进程资源,又可以独立调度
②使用内核实现线程
- 内核线程就是直接由操作系统内核支持的线程,这种线程有内核来完成线程切换,内核通过调度器对线程进行调度,并负责将线程任务映射到各个处理器上
- 程序一般不会直接使用内核线程,而是使用内核线程的高级接口——轻量级进程,每个轻量级进程都由一个内核线程支持
③使用用户线程实现
- 用户线程的建立、同步、销毁和调度完全在用户态中完成,不需要内核的帮助
④使用用户线程加轻量级进程混合实现
- 用户线程还是完全建立在用户空间中,因此用户线程的创建、切换、析构等操作依然廉价,并且可以支持大规模的用户线程并发。轻量级进程则作为用户线程和内核线程之间的桥梁,这样可以使用内核提供的线程调度功能及处理器映射,并且用户线程的系统调用要通过轻量级线程来完成,大大降低了整个进程被完全阻塞的风险。
7.协同式调度
①协同式调度的多线程系统,线程执行时间由线程本身来控制,线程把自己的工作执行完成后,主要通知系统切换到另一个线程上
②线程要把自己的事情干完以后才会进行线程切换,切换操作对线程自己是可知的,所以没有线程同步问题
③缺点是:线程执行时间不可控,如果线程编写有问题,一直不告诉操作系统进行切换,那么程序会一直阻塞在哪里
8.抢占式调度
①每个线程将由操作系统来分配时间,线程的切换不由线程本身来决定,线程的执行时间是系统可控的。
②Java使用的线程调度方式是抢占式调度
9.状态转换
①新建:创建后尚未启动的线程处于这种状态
②运行:包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程有可能正在执行,也有可能正在等待CPU分配时间片
③无限期等待:处于这种状态的线程不会被分配CPU执行时间,他们要等待被其他线程显示的唤醒
- 没有设置Timeout参数的Object.wait()方法
- 没有设置Timeout参数的Thread.join()方法
- LockSupport.park()方法
④限期等待:处于这种状态的线程也不会被分配CPU执行时间,不过无须等待被其他线程显示的唤醒,在一定时间以后会有操作系统自动唤醒
- Thread.sleep()方法
- 设置了Timeout参数的Object.wait()方法
- 设置了Timeout参数的Thread.join()方法
- LockSupport.parkNanos()方法
- LockSupport.parkUntil()方法
⑤阻塞:线程被阻塞了,“阻塞状态”与“等待状态”的区别是:“阻塞状态”在等待着获取到一个排它锁,这个事件将在另外一个线程放弃这个锁的时候发生;“等待状态”则是在等待一段时间或者唤醒动作
⑥结束:已终止的线程状态,线程已结束执行