当前位置: 代码网 > 服务器>服务器>Tomcat > tomcat获取执行的线程池信息和线程堆栈的方法详解

tomcat获取执行的线程池信息和线程堆栈的方法详解

2024年05月14日 Tomcat 我要评论
最近打算还是了解点java吧,搞点小demo。想了解的知识点:数据请求的堆栈,因为遇到过数据库锁表需要定位。(今天做点记录,但有点不完美)想得到数据库连接没释放的那个线程堆栈。找个access访问记录

最近打算还是了解点java吧,搞点小demo。

想了解的知识点:

  • 数据请求的堆栈,因为遇到过数据库锁表需要定位。(今天做点记录,但有点不完美)
  • 想得到数据库连接没释放的那个线程堆栈。
  • 找个access访问记录的排序工具类。

线程池信息获取

  • 线程池信息获取或者告警可以用 dynamic-tp
  • 获取tomcat的线程信息可以用下面的代码
//获取webserver线程池
threadpoolexecutor executor = (threadpoolexecutor) ((tomcatwebserver) applicationcontext.getwebserver())
        .gettomcat()
        .getconnector()
        .getprotocolhandler()
        .getexecutor();
map<string, string> returnmap = new linkedhashmap<string, string>();
returnmap.put("核心线程数", string.valueof(executor.getcorepoolsize()));
returnmap.put("最大线程数", string.valueof(executor.getmaximumpoolsize()));
returnmap.put("活跃线程数", string.valueof(executor.getactivecount()));
returnmap.put("池中当前线程数", string.valueof(executor.getpoolsize()));
returnmap.put("历史最大线程数", string.valueof(executor.getlargestpoolsize()));
returnmap.put("线程允许空闲时间/s", string.valueof(executor.getkeepalivetime(timeunit.seconds)));
returnmap.put("核心线程数是否允许被回收", string.valueof(executor.allowscorethreadtimeout()));
returnmap.put("提交任务总数", string.valueof(executor.getsubmittedcount()));
returnmap.put("历史执行任务的总数(近似值)", string.valueof(executor.gettaskcount()));
returnmap.put("历史完成任务的总数(近似值)", string.valueof(executor.getcompletedtaskcount()));
returnmap.put("工作队列任务数量", string.valueof(executor.getqueue().size()));
returnmap.put("拒绝策略", executor.getrejectedexecutionhandler().getclass().getsimplename());
system.out.println(returnmap);

获取tomcat的线程堆栈信息

首先需要了解下线程的状态:

1.new(创建)创建态:当一个已经被创建的线程处于未被启动时,即:还没有调用start方法时,就处于这个状态。

2.runnable(运行时)运行态:当线程已被占用,在java虚拟机中正常执行时,就处于此状态。

3.blocked(排队时)阻塞态:当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入blocked状态。当该线程持有锁时,该线程将自动变成runnable状态。

4.waiting(休眠)休眠态:一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入waiting状态。进入这个状态后是不能自动唤醒的,必须等待另一个线程调用notify或者notifyall方法才能够唤醒。

5.timed_waiting (指定休眠时间)指定时间休眠态:基本同waiting状态,多了个超时参数,调用对应方法时线程将进入timed_waiting状态,这一状态将一直保持到超时期满或者接收到唤醒通知,带有超时参数的常用方法有thread.sleep、锁对象.wait() 。

6.terminated (结束)结束态:从runnable状态正常退出而死亡,或者因为没有捕获的异常终止了runnable状态而死亡。

系统启动的线程有哪些

count:18
方法2:线程池的线程:thread[catalina-utility-1,1,main]
方法2:线程池的线程:thread[catalina-utility-2,1,main]
方法2:线程池的线程:thread[container-0,5,main]
方法2:线程池的线程:thread[file watcher,5,main]
方法2:线程池的线程:thread[live reload server,5,main]
-----------------名字包含了http 默认初始10个线程
-----------------acceptor线程主要用于监听套接字,将已连接套接字转给poller线程。
-----------------poller线程主要用于以较少的资源轮询已连接套接字以保持连接,当数据可用时转给工作线程。
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-1,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-2,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-3,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-4,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-5,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-6,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-7,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-8,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-9,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-exec-10,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-poller,5,main]
方法2:线程池的线程:thread[http-nio-0.0.0.0-8089-acceptor,5,main]
--------------------
方法2:线程池的线程:thread[destroyjavavm,5,main]

代码

thread mainthread = thread.currentthread();
threadgroup mainthreadthreadgroup = mainthread.getthreadgroup();
//获取线程组中的线程。
int count = mainthreadthreadgroup.activecount();
system.out.println("count:"+count);
thread[] threads = new thread[count];
//enumerate 枚举,recurse 递归
mainthreadthreadgroup.enumerate(threads, true);
stream.of(threads).filter(thread::isalive).foreach(thread -> system.out.println("方法2:线程池的线程:" + thread ));

http的线程根据上面的信息

waiting状态的排除,名字做点过滤,去掉当前线程,因为从上面得到的线程池不知道怎么得到线程,这里拿到所有做过滤。

map<thread, stacktraceelement[]> allthread = thread.getallstacktraces();
for (thread t : allthread.keyset()) {
/**
 * 一个线程可以在给定时间点处于一个状态。 这些状态是不反映任何操作系统线程状态的虚拟机状态。
 *
 * 线程状态。 线程可以处于以下状态之一:
 * new              尚未启动的线程处于此状态。
 * runnable         在java虚拟机中执行的线程处于此状态。
 * blocked          被阻塞等待监视器锁定的线程处于此状态。
 * waiting          正在等待另一个线程执行特定动作的线程处于此状态。
 * timed_waiting    正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
 * terminated       已退出的线程处于此状态。
 * */
    stringbuilder sb=new stringbuilder();
    if(!thread.state.waiting.equals(t.getstate()) &&
       t.getname().indexof("http")>-1 &&
       !thread.currentthread().equals(t)) {
        system.out.println(t.getname()+":"+t.getstate());
        sb.setlength(0);
        for (stacktraceelement ele : t.getstacktrace()) {
            sb.append(ele.getclassname()).append(".").append(ele.getmethodname()).append(".").append(ele.getfilename()).append("$").append(ele.getlinenumber()).append("\n");
        }
        system.out.println(sb.tostring());
    }
}

测试

@requestmapping(value = "/hello")
public string testhello(model model) throws interruptedexception {
    thread.sleep(5000);
    model.addattribute("currenttime", new date());
    return "hello";
}

@requestmapping(value = "/hello2")
public string testhello2(model model) throws interruptedexception {
    for(int i=0;i<integer.max_value;i++){
        for(int j=0;j<integer.max_value;j++){}
    }
    model.addattribute("currenttime", new date());
    return "hello";
}

以上就是tomcat获取执行的线程池信息和线程堆栈的方法详解的详细内容,更多关于tomcat线程池信息和线程堆栈的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com