ThreadPoolExecutor中运行线程名称的修改

来源:互联网 发布:软件开发课程设计 编辑:程序博客网 时间:2024/06/04 18:23

项目中使用到了ThreadPoolExecutor,这个是挺好的东西,线程池的实现。但有一点不太爽的是,用Jprofiler调试由它创建的线程的时候,看到的都是pool-1-thread-1\2\3\4之类的。这是它自身的默认规则产生的,pool代表这是池,-1-代表是第几个ThreadPoolExecutor产生的,-thread-1是递增的。

所以每次我都要点 Thread Dumps 去查看线程执行的具体的代码与堆栈信息,推测是哪个地方出的问题。虽然说也能看出来,但很不直观嘛。于是有了一个想法,能不能不要用它的默认名称,由我自己的设定线程的名字,这样就一目了然了。把idea和master王说了,觉得也是个好主意。当然就只是在开发阶段有帮助,系统稳定上线后就没有用了。

 Executors.defaultThreadFactory()是缺省的创建线程的实现。看下源码,

public ThreadPoolExecutor(int corePoolSize,                              int maximumPoolSize,                              long keepAliveTime,                              TimeUnit unit,                              BlockingQueue<Runnable> workQueue) {        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,             Executors.defaultThreadFactory(), defaultHandler);
之所以在工具中看到所有的线程都是以 pool- 开头的,那是因为人家就是写死的。
    static class DefaultThreadFactory implements ThreadFactory {        private static final AtomicInteger poolNumber = new AtomicInteger(1);        private final ThreadGroup group;        private final AtomicInteger threadNumber = new AtomicInteger(1);        private final String namePrefix;        DefaultThreadFactory() {            SecurityManager s = System.getSecurityManager();            group = (s != null) ? s.getThreadGroup() :                                  Thread.currentThread().getThreadGroup();            namePrefix = "pool-" +                          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;        }    }
我想要改成的格式是 pool-prjname-具体thread-1这种形式,如果说项目中所有代码共用一个pool,我可以直接把 poolNumber.getAndIncrement() 换成想要的名称。没错。但是具体thread呢?再搞一个参数,从上层传递进来替换吗?最开始发现貌似可以的。当然了,这意味着原生的Executors不能用了,把所有代码都copy到一个新类里,可能还会关联到其他类,也一并copy,如果不是关联到很多类的话,还是可以的。如果一层又一层,就比较没意思了。

使用方式:pool.taskPressIn(msgThread, "发送tmp"); 发送tmp就是我想要的具体thread的名称。但通过工具多次观察后,发现thread名称不是传进去的那个。认真考虑了newCachedThreadPool这个池,它是线程可复用的。当我提交了一个带名称的任务实例后,池子里其实是有空闲的线程的,这些线程可能就是之前命过名的,直接运行实例了,名称也就不会变了。

我最开始想着从池子中使用的线程入手,用的哪个就改哪个的名称,由于跟代码,想发现任务execute时,怎么获取线程的,master王想了一个办法。

我们说一个线程在start后才会执行run方法,run方法的执行表示这个task真正被线程运行了,这时线程的名称也就确定了。所以可以在run的第一句加上       

Thread.currentThread().setName(ThreadPoolFairEx.renameThread(Thread.currentThread(), this.threadName));
Thread.currentThread()把当前的运行的线程传进去,renameThread()是一个替换string的方法而已,把自定义的threadName替之。然后currentThread再setName。这样就是这种效果




0 0
原创粉丝点击