实现线程的主要方式:
1) 使用内核实现(1:1实现,JDK线程模型采用方式)
内核线程(KLT)就是直接由操作系统内核支持的线程,由内核完成线程切换,内核通过操纵调度器对线程进行调度,并负责将线程的任务映射到各个处理器上.程序一般使用内核线程的一种高级接口-轻量级进程(LWP),由于每个轻量级进程都由一个内核线程支持,只有先支持内核线程才能有轻量级进程.
局限性:由于基于内核线程实现,各种线程操作,如创建,析构和同步,都需要进行系统调用,在用户态和内核态来回切换.其次每个轻量级进程都需要一个内核线程的支持,因此轻量级进程需要消耗一定的内核资源,所以一个系统支持轻量级进程的数量是有限的
2) 使用用户线程实现(1:N实现)
用户线程一般指的是完全建立在用户空间的线程库上,系统内核不能感知到用户线程的存在和实现,用户线程的建立,同步,销毁和调度完全在用户态中完成,不需要内核帮助.
局限性:线程的操作都需要用户线程自己处理,操作系统只将处理器资源分配到进程,"阻塞的处理"和"多处理器系统如何将线程映射到其他处理器上"解决比较困难.
3) 使用用户线程加轻量级进程混合实现(N:M实现)
1. 新建(NEW):创建后尚未启动的线程处于这种状态
2. 运行(Runnable):包括操作系统线程状态的Running和Ready,可能正在执行或者等待操作系统分配执行时间
3. 无限期等待(Waiting):处于该状态的线程不会被分配处理器执行时间,需要被其他线程显式唤醒,以下方法会让线程陷入无限期的等待状态:
1) 没有设置timeout参数的Object::wait()方法
2) 没有设置timeout参数的Thread::join()方法
3) LockSupport::park()方法
4.限期等待(Timed Waiting):处于该状态的线程也不会被分配处理器执行时间,无需其他线程显式唤醒,一定时间后由系统自动唤醒,以下方法会让线程陷入限期等待状态:
1) Thread::sleep()方法
2) 设置timeout参数的Object::wait()方法
3) 设置timeout参数的Thread::join()方法
4) LockSupport::parkNano()方法
5) LockSupport::partUntil()方法
5. 阻塞(Blocked):线程被阻塞了,阻塞和等待状态的区别在于阻塞状态等待着获取到一个排它锁,这个事件将在另一个线程放弃这个锁的时候发生;等待状态则是在等待一段时间,或者唤醒动作的发生.一般程序等待进入同步区域时,线程将进入这种状态
6.结束(Terminated):已终止线程的线程状态,线程已经结束执行.
Thread的线程栈容量如果不通过-Xss或-XX:ThreadStackSize设置,默认是1MB,此外内核数据结构(Kernel Data Structures)会额外消耗16KB内存.