Java5之后线程状态放到了Thread.State中,分别是:
- new:就绪状态,表示线程被创建出来还没有启动。
- Runnabel:就绪状态,线程执行需要对应的计算资源,此时线程可能正在执行,也可能在等待CPU调度。
- Blocked:阻塞状态,表示线程在等待持有Monitor锁,如果此时锁被其他线程抢占,则当前线程进入阻塞状态。
- Waiting:等待状态,表示执行状态尚未满足在等待其他线程的针对性操作,比如notify等操作。
- Terminated:终止状态,意外退出或者,线程执行完成。
在操作系统中线程是最小的调度单元,进程中可以创建多个线程,线程中有自己的栈,寄存器,本地存储,会和进程内其他线程共享文件描述符,虚拟地址。
目前jdk中调度的线程会一一映射到操作系统的内核线程上,jdk通过JNI调用本地代码。
最近几年golang的协程很火,相信过不了多久java也会出现这样一款轻量级并发解决方案了。
创建线程有Runable和继承Thread两种方式,其实底层是一种方式基于Runable的,好处是解决了Java类不支持多重继承的限制,可以重用代码逻辑。
Jdk层面对于线程的调度,可以采用yield让线程让出cpu,调用wait告诉持有monitor锁的线程进入等待状态。
当我们启动一个hello word时,可以通过MXBean观察启动的线程,观察他们的不同目的:
- main:主线程。
- Reference Handler:对引用对象进行垃圾回收的线程。
- Finalizer:处理用户的Finalizer方法。
- Signal Dispatcher:接收jvm外部命令,命令转发器。
- Attach Listerner:负责接收jstack,jmap的命令。