jstack如何区分JVM级别线程和用户级别线程

小编 145

jstack如何区分JVM级别线程和用户级别线程,需要具体问题具体分析。JVM级别线程会在jvm启动时就会存在,而用户线程则是在用户访问时才会生成;此外,JVM级别线程是为JVM内部功能提供服务的,大部分独立于正在进行的进程;而用户级线程通常位于应用程序级。

1.JVM级别线程

JVM级别线程实际上是指JVM内部的后台线程,它们大部分独立于正在进行的进程,往往在JVM初始化的时候就存在,并由操作系统执行。操作系统需要这些线程来执行诸如内存管理(譬如垃圾回收或低内存的检测)、进程管理等任务。

由于JVM级别线程负责维护、执行和报告操作系统所需的进程,因此其创建和管理成本更高,并且这些线程的上下文切换很慢。此外,大多数内核级线程不能被用户级线程抢占。

2.用户级别的线程

与JVM级别线程不同的是,用户级别的线程是在用户访问时才会生成,它会根据用户请求的不同而发生变化。该类线程的运行情况往往是我们所关注的重点,而且这一部分也是最容易产生死锁的地方。

用户级线程通常位于应用程序级,在此应用程序创建这些线程以维持其在主内存中的执行。除非需要,否则这些线程与内核线程隔离工作。因为它们不必引用许多寄存器,并且上下文切换比内核级线程快得多,所以它们更易于创建。

延伸阅读

JVM线程状态都有哪几种

JVM线程状态有五种,即新生状态(New)、就绪状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)、死亡状态(Dead)。

1.新生状态(New)

当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后,此时该线程处于新生(new)状态,处于新生状态的线程有自己的内存空间,但该线程并没有运行,此时线程还不是活着的(notalive)。

2.就绪状态(Runnable)

通过调用线程实例的start()方法来启动线程使线程进入就绪状态(runnable);处于就绪状态的线程已经具备了运行条件,但还没有被分配到CPU即不一定会被立即执行,此时处于线程就绪队列,等待系统为其分配CPCU,等待状态并不是执行状态;此时线程是活着的(alive)。

3.运行状态(Running)

一旦获取CPU(被JVM选中),线程就进入运行(running)状态,线程的run()方法才开始被执行;在运行状态的线程执行自己的run()方法中的操作,直到调用其他的方法而终止、或者等待某种资源而阻塞、或者完成任务而死亡;如果在给定的时间片内没有执行结束,就会被系统给换下来回到线程的等待状态;此时线程是活着的(alive)。

4.阻塞状态(Blocked)

通过调用join()、sleep()、wait()或者资源被暂用使线程处于阻塞(blocked)状态;处于Blocking状态的线程仍然是活着的(alive)。

5.死亡状态(Dead)

当一个线程的run()方法运行完毕或被中断或被异常退出,该线程到达死亡(dead)状态。此时可能仍然存在一个该Thread的实例对象,当该Thread已经不可能在被作为一个可被独立执行的线程对待了,线程的独立的callstack已经被dissolved。一旦某一线程进入Dead状态,他就再也不能进入一个独立线程的生命周期了。对于一个处于Dead状态的线程调用start()方法,会出现一个运行期(runtimeexception)的异常;处于Dead状态的线程不是活着的(notalive)。

回复

我来回复
  • 暂无回复内容

注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部