Java与线程

Thread类与大部分的Java类库API有明显区别,所有关键方法都声明为Native

Java类库API中,一个Native方法往往就意味这这个方法没有使用或无法使用

平台无关的手段来实现。(也可能是为了执行效率而使用Native方法)

线程的实现

  • 内核线程实现(1:1实现)

    内核线程的调度成本主要来自用户态与核心态之间的状态转换,而这两种

    状态切换的开销主要来自于响应中断、保护和恢复执行现场的成本。

  • 用户线程实现(1:N实现)

  • 用户线程+轻量级进程混合实现(N:M实现)

Java线程的实现

HotSpot的每个线程都是直接映射到一个操作系统原生线程来实现。(采用1:1的线程模型)

这种映射到操作系统上的线程天然的缺陷是切换、调度成本高昂,系统能容纳的

线程数量也有限。

HotSpot自己不会干涉线程调度,全权交给操作系统去处理,何时冻结或唤醒线程、该给线程

分配多少处理器时间、该把线程安排给哪个处理器核心去执行等,都是由操作系统完成的,

也都是由操作系统全权决定的。

Java线程调度

Java使用的线程调度方式是抢占时调度。

Java线程调度是系统自动完成的,但可以“建议”操作系统给某些线程多分配一些时间。

调优点?

线程状态转化

Java语言定义了6种线程状态,在任意一个时间点中,一个线程只能有且只有其中的一种状态。

  • 新建(New):创建后尚未启动的线程处于这种状态。

  • 运行(Runnable):包括操作系统线程状态中的RunningReady

  • 无限期等待(Waiting):处于这种状态的线程不会被分配处理器执行时间,需要等待其他

    线程显示唤醒。以下方法会让线程进入无限期的等待状态。

    • 没有设置Timeout参数的Object::wait()方法
    • 没有设置Timeout参数的Thread::join()方法
    • LockSupport::park()方法
  • 限期等待(Timed Waiting):处于这种状态的线程也不会被分配处理器执行时间,不过

    无须等待其他线程显示唤醒,在一定时间后它们会由系统自动唤醒。

    • Thread::sleep()方法
    • 设置了Timeout参数的Object::wait()方法
    • 设置了Timeout参数的Thread::join()方法
    • LockSupport::parkNanos()方法
    • LockSupport::parkUntil()方法
  • 阻塞(Blocked):线程被阻塞了,阻塞状态是线程在等待获取到一个排它锁,这个事件

    将在另外一个线程放弃这个锁的时候发生。

  • 结束(Terminated):已终止线程的线程状态,线程已经结束执行。