操作系统、进程、线程的关系
- 操作系统将资源分配给进程,进程将资源分配给线程。但是CPU资源比较特殊,CPU资源是直接分配给线程的。
- 一个进程中至少会有一个线程,进程不能脱离进程而存在。
- main函数启动的时候,会产生JVM进程,JVM进程会产生多条线程。main函数线程称为主线程。还有产生GC回收的守护线程。
JVM内存模型与线程的关系
虽然对象是存在Java堆中的,但是对象的引用存放在虚拟机栈中。
使用JDK工具观察线程
注意,如果没有将对应的命令加入到环境变量中,需要到JDK所在路径的bin目录下执行。
在观察的时候,可以让main线程Sleep(Integer.MAX_VALUE),目的是为了让JVM进程不停止,这样才能观察到线程。
jps -lvm 可以看到系统中运行的进程。在使用jcmd的时候,需要带上进程的id。
- jcmd
- jstack
- 可视化工具 jvisualvm 有动态图查看线程的运行状态
- 可视化工具 jconsole 可以查看Thread等类的属性等信息,可以单独对某个线程查看,可以检测死锁
线程的状态
线程的性能问题
上下文切换可以认为是内核(操作系统的核心)在 CPU 上对于进程(包括线程)进行以下的活动:(1)挂起一个进程,将这个进程在 CPU 中的状态(上下文)存储于内存中的某处,(2)在内存中检索下一个进程的上下文并将其在 CPU 的寄存器中恢复,(3)跳转到程序计数器所指向的位置(即跳转到进程被中断时的代码行),以恢复该进程。
缓存开销:CPU重新缓存
何时会导致密集的上下文切换:频繁地竞争锁,或者由于IO读写等原因导致频繁阻塞
协作:内存同步
为了数据的正确性,同步手段往往会使用禁止编译器优化、使CPU内的缓存失效