JUC讲解:使用 stack log(jstack、jps)

JUC讲解:使用 stack log(jstack、jps)

stack log是通过命令行来查看线程状态的手段,这篇文章着重介绍其用法

使用

为了演示,我写了一段Demo,这段 Demo里包含“wait()线程”,“sleep线程”,“被阻塞的线程”三类线程,我们待会要在stack log 中找到这些线程

代码贴出来:

    public static void main(String[] args) throws InterruptedException {

        new Thread(new WaitingThread(), "waitingThread").start();
        new Thread(new SleepingThread(), "sleepThread").start();
        new Thread(new BlockedThread(), "blockedThread-1").start();
        new Thread(new BlockedThread(), "blockedThread-2").start();
    }

    static class WaitingThread implements Runnable {

        @Override
        public void run() {
            synchronized (WaitingThread.class) {
                try {
                    WaitingThread.class.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    static class SleepingThread implements Runnable {

        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(1000000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    static class BlockedThread implements Runnable {

        @Override
        public void run() {
            synchronized (BlockedThread.class) {
                while (true) {
                    try {
                        Thread.sleep(1000000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }

  • WaitingThread 类:测试被 wai() 的线程
  • SleepingThread 类:测试睡眠的线程
  • BlockedThread 类,测试被阻塞的线程

在 main 中创建这些线程,可以看到我创建了两个 BlockedThread,目的是模拟阻塞的效果

运行程序后,在 cmd 中,输入 “jps”命令,找到程序入口类,再通过 “jstack 进程号”来查看 stack log

怎么看呢?

我们可以在输出的log日志中找到很多正在运行的线程,有一些是 main 函数自带的,我们不用管它,我们找我们创建的 thread

在 main 函数运行的时候,会自动创建出六七个线程,我会挑一些讲解,我们先看看我们自己写的线程。

直接查找线程名就可以找到了

先看看我们自己写的线程

waitingThread”:

image-20240311194338287

sleepThread

image-20240311194432033

“blockedThread-2”

image-20240311194528175

再看几个在main启动时自带的线程

一些线程即使我们没有定义,在main启动中也会自带几个,我们挑出几个简单讲解

“Finalizer”: 垃圾回收线程

线程的状态是 WAITING,因为此时没有类需要被回收,所以处于 wait() 状态,当需要回收时会被 notify() 唤醒,值得一提的是,这个 notify() 需要用到 Signal Dispatcher 线程(同样是随着main启动的线程),Signal Dispatcher 线程 用于传输命令

image-20240311194735052

“Reference Handler”: 控制 强、弱、软、虚 引用的线程

是 wai() 状态

为什么呢?

  1. 没有垃圾收集了,不需要使用强弱引用

  2. 目前线程已经全部完成引用了, 不需要再引用处理了

image-20240311194911550

就讲到这里了!

感谢B站up 河北王校长 的知识分享

posted @ 2024-03-11 20:02  yangruomao  阅读(37)  评论(0编辑  收藏  举报