1 lsof -i :8084 查看端口程序
2.top -H -p #pid查看相关线程,找出最占资源的线程
3.printf '0x\n' #线程ID(即2中pid)得到线程ID的16进制
4.jstack #pid|grep -A 10 线程ID的16进制
查看进程中所有的线程
jstack #pid|grep nid=0x
查看gc相关的线程号
jstack #pid| grep nid=ox| grep GC | awk '{print "pid=" strtonum("0x"substr($7,7,12))" " $0}'
查看自定义线程池(线程池的名字为xxxTreadPool)相关的线程号
jstack #pid|grep TreadPool- |awk '{print "pid=" strtonum("0x"substr($6,7,12))" " $0}'
查看http-nio-线程
jstack #pid|grep http-nio- |awk '{print "pid=" strtonum("0x"substr($7,7,12))" " $0}'
springboot web程序举例
查看pid
top -H -p 122349
ps -T -p 122349
spring boot web程序进程相关线程
jstack 122349|grep nid=0x|awk '{from=(index($0,"nid=0x")+6);to=(from+5);pid=substr($0,from);pid=substr(pid,0,5);pid=strtonum("0x"pid);print "pid="pid " " substr($0,0,100)}'
结果:黄色部分为自定义线程池,绿色部分为容器相关的线程,剩余是top能看到进程
pid=122941 "ScheduledThreadPool-1-thread-5" #43 prio=5 os_prio=0 tid=0x00007f3ba8004800 nid=0x1e03d waiting on pid=122940 "ScheduledThreadPool-1-thread-4" #42 prio=5 os_prio=0 tid=0x00007f3b98001000 nid=0x1e03c waiting on pid=122939 "ScheduledThreadPool-1-thread-3" #41 prio=5 os_prio=0 tid=0x00007f3ba8002800 nid=0x1e03b waiting on pid=122937 "ScheduledThreadPool-1-thread-2" #40 prio=5 os_prio=0 tid=0x00007f3ba8001000 nid=0x1e039 waiting on pid=122935 "CustomizedThreadPool-1-thread-3" #39 prio=5 os_prio=0 tid=0x00007f3bf8175000 nid=0x1e037 waiting on pid=122934 "CustomizedThreadPool-1-thread-2" #38 prio=5 os_prio=0 tid=0x00007f3bf8173000 nid=0x1e036 waiting on pid=122933 "CustomizedThreadPool-1-thread-1" #37 prio=5 os_prio=0 tid=0x00007f3bf818e000 nid=0x1e035 waiting on pid=122932 "ScheduledThreadPool-1-thread-1" #36 prio=5 os_prio=0 tid=0x00007f3bf818b800 nid=0x1e034 waiting on pid=122931 "FixedThreadPool-1-thread-3" #35 prio=5 os_prio=0 tid=0x00007f3bf8189800 nid=0x1e033 waiting on cond pid=122930 "FixedThreadPool-1-thread-2" #34 prio=5 os_prio=0 tid=0x00007f3bf8188000 nid=0x1e032 waiting on cond pid=122929 "FixedThreadPool-1-thread-1" #33 prio=5 os_prio=0 tid=0x00007f3bf8191000 nid=0x1e031 waiting on cond pid=122583 "Attach Listener" #32 daemon prio=9 os_prio=0 tid=0x00007f3c2c001000 nid=0x1ded7 waiting on conditio pid=122350 "DestroyJavaVM" #31 prio=5 os_prio=0 tid=0x00007f3c74009000 nid=0x1ddee waiting on condition [0x0000 pid=122387 "http-nio-8084-Acceptor-0" #29 daemon prio=5 os_prio=0 tid=0x00007f3c74ef0000 nid=0x1de13 runnable [ pid=122386 "http-nio-8084-ClientPoller-1" #28 daemon prio=5 os_prio=0 tid=0x00007f3c75263800 nid=0x1de12 runnab pid=122385 "http-nio-8084-ClientPoller-0" #27 daemon prio=5 os_prio=0 tid=0x00007f3c750a1800 nid=0x1de11 runnab pid=122384 "http-nio-8084-exec-10" #26 daemon prio=5 os_prio=0 tid=0x00007f3c7527a800 nid=0x1de10 waiting on co pid=122383 "http-nio-8084-exec-9" #25 daemon prio=5 os_prio=0 tid=0x00007f3c7438a000 nid=0x1de0f waiting on con pid=122382 "http-nio-8084-exec-8" #24 daemon prio=5 os_prio=0 tid=0x00007f3c75087800 nid=0x1de0e waiting on con pid=122381 "http-nio-8084-exec-7" #23 daemon prio=5 os_prio=0 tid=0x00007f3c750f5000 nid=0x1de0d waiting on con pid=122380 "http-nio-8084-exec-6" #22 daemon prio=5 os_prio=0 tid=0x00007f3c750f7000 nid=0x1de0c waiting on con pid=122379 "http-nio-8084-exec-5" #21 daemon prio=5 os_prio=0 tid=0x00007f3c74cec800 nid=0x1de0b waiting on con pid=122378 "http-nio-8084-exec-4" #20 daemon prio=5 os_prio=0 tid=0x00007f3c74ef5000 nid=0x1de0a waiting on con pid=122377 "http-nio-8084-exec-3" #19 daemon prio=5 os_prio=0 tid=0x00007f3c7477b000 nid=0x1de09 waiting on con pid=122376 "http-nio-8084-exec-2" #18 daemon prio=5 os_prio=0 tid=0x00007f3c74e9e000 nid=0x1de08 waiting on con pid=122375 "http-nio-8084-exec-1" #17 daemon prio=5 os_prio=0 tid=0x00007f3c74f1f800 nid=0x1de07 waiting on con pid=122374 "NioBlockingSelector.BlockPoller-1" #16 daemon prio=5 os_prio=0 tid=0x00007f3c74f1e800 nid=0x1de06 r pid=122373 "container-0" #15 prio=5 os_prio=0 tid=0x00007f3c752d5800 nid=0x1de05 waiting on condition [0x00007f pid=122372 "Catalina-utility-2" #14 prio=1 os_prio=0 tid=0x00007f3c08406800 nid=0x1de04 waiting on condition [0 pid=122371 "Catalina-utility-1" #13 prio=1 os_prio=0 tid=0x00007f3c74cf5800 nid=0x1de03 waiting on condition [0 pid=122367 "Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007f3c7422c000 nid=0x1ddff runnable [0x000000000 pid=122366 "C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007f3c7420f000 nid=0x1ddfe waiting on condit pid=122365 "C2 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f3c7420c800 nid=0x1ddfd waiting on condit pid=122364 "C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f3c7420b000 nid=0x1ddfc waiting on condit pid=122363 "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f3c74208000 nid=0x1ddfb waiting on condit pid=122362 "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f3c74206800 nid=0x1ddfa runnable [0x000000 pid=122361 "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f3c741d3800 nid=0x1ddf9 in Object.wait() [0x00007f pid=122360 "Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f3c741d0800 nid=0x1ddf8 in Object.wait() pid=122359 "VM Thread" os_prio=0 tid=0x00007f3c741c7000 nid=0x1ddf7 runnable pid=122351 "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f3c7401e800 nid=0x1ddef runnable pid=122352 "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f3c74020000 nid=0x1ddf0 runnable pid=122353 "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f3c74022000 nid=0x1ddf1 runnable pid=122354 "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f3c74024000 nid=0x1ddf2 runnable pid=122355 "GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007f3c74025800 nid=0x1ddf3 runnable pid=122356 "GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007f3c74027800 nid=0x1ddf4 runnable pid=122357 "GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007f3c74029800 nid=0x1ddf5 runnable pid=122358 "GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007f3c7402b000 nid=0x1ddf6 runnable pid=122368 "VM Periodic Task Thread" os_prio=0 tid=0x00007f3c74239000 nid=0x1de00 waiting on condition
附java代码
package com.example.demo.threadmanage; import com.example.demo.threadmanage.scheduler.NamedThreadFactory; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; import java.util.concurrent.*; /** * Created by Administrator on 2020/2/5. */ @Service public class ExecutorsTest { public static void main(String[] args) { ExecutorsTest.threadPoolTest(); } public static void threadPoolTest() { /** * 创建一个可缓存的线程池 * 线程池为无限大,当执行当前任务时上一个任务已经完成,会复用执行上一个任务的线程,而不用每次新建线程 */ ExecutorService cachedThreadPool= Executors.newCachedThreadPool(); //executeThreadPool(cachedThreadPool); /** * 创建一个可重用固定个数的线程池 *因为线程池大小为3,每个任务输出打印结果后sleep 2秒,所以每两秒打印3个结果。 *定长线程池的大小最好根据系统资源进行设置 */ ExecutorService fixedThreadPool=Executors.newFixedThreadPool(3,new NamedThreadFactory("FixedThreadPool")); executeThreadPool(fixedThreadPool); /** * 创建一个定长线程池,支持定时及周期性任务执行----延迟执行 */ ScheduledExecutorService scheduledThreadPool=Executors.newScheduledThreadPool(5,new NamedThreadFactory("ScheduledThreadPool")); // scheduledThreadPool.schedule(()->{ // System.out.println("延迟2秒执行"); // },2, TimeUnit.SECONDS); scheduledThreadPool.scheduleAtFixedRate(()->{ System.out.println("延迟2秒后,每3秒执行一次"+getNowTime()+" 线程名称:"+Thread.currentThread().getName()); },2,3, TimeUnit.SECONDS); /** * 创建一个单线程化的线程池 *创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务, * 保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 */ ExecutorService singleThreadExecutor=Executors.newSingleThreadExecutor(); // executeThreadPool(singleThreadExecutor); /** * 自定义线程池ThreadPoolExecutor */ //创建数组型缓冲等待队列 BlockingQueue<Runnable> bq = new ArrayBlockingQueue<>(10); ThreadPoolExecutor tpe=new ThreadPoolExecutor(3,6,50,TimeUnit.SECONDS,bq,new NamedThreadFactory("CustomizedThreadPool")); tpe.execute(new TempThread()); tpe.execute(new TempThread()); tpe.execute(new TempThread()); tpe.execute(new TempThread()); tpe.execute(new TempThread()); tpe.execute(new TempThread()); tpe.execute(new TempThread()); tpe.execute(new TempThread()); tpe.execute(new TempThread()); tpe.execute(new TempThread()); tpe.execute(new TempThread()); // tpe.shutdown(); } public static String getNowTime(){ SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); return df.format(new Date()); } public static void executeThreadPool(ExecutorService executorService){ for (int i = 0; i < 10; i++) { System.out.println("thread order is =="+i); try{ //sleep可明显看到使用的是线程池里面以前的线程,没有创建新线程 Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); } executorService.execute(()->{ System.out.println(Thread.currentThread().getName()+"正在被执行"); }); } } } class TempThread implements Runnable{ @Override public void run() { try{ //sleep可明显看到使用的是线程池里面以前的线程,没有创建新线程 Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"正在被执行 "+ExecutorsTest.getNowTime()); } }
线程工厂
package com.example.demo.threadmanage.scheduler; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; /** * Created by Administrator on 2020/2/8. */ public class NamedThreadFactory implements ThreadFactory { private final AtomicInteger poolNumber = new AtomicInteger(1); private final ThreadGroup group; private final AtomicInteger threadNumber = new AtomicInteger(1); private final String namePrefix; public NamedThreadFactory(String name) { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); if(null==name || "".equals(name.trim())){ name="pool"; } namePrefix = name+"-" + poolNumber.getAndIncrement() + "-thread-"; } public Thread newThread(Runnable r) { Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); if (t.isDaemon()) t.setDaemon(false); if (t.getPriority() != Thread.NORM_PRIORITY) t.setPriority(Thread.NORM_PRIORITY); return t; } }