写点什么

Java 线程命名问题解决

  • 2024-12-16
    福建
  • 本文字数:1426 字

    阅读完需:约 5 分钟

前言


网上冲浪时刷到线程池的文章,想想看自己好像还没在实际场景中设置过线程名称,小小研究一下。


研究过程


默认命名


创建的线程都会有自己的名字,如果不设置,程序会给线程默认的名字,如Thread-0


Thread t = new Thread(() -> {    System.out.println(Thread.currentThread().getName());});t.start();// Thread-0
复制代码


设置线程名称,应当有个理由。现在一个项目中有订单相关线程池、有付款相关线程池,给线程命名,可以容易区分线程种类。如Thread-order-0Thread-fund-0


Thread 内部实现原理


首先我们打开 Thread 类,属性 name 就是线程的名称。


publicclass Thread implements Runnable {    /* Make sure registerNatives is the first thing <clinit> does. */    private static native void registerNatives();    static {        registerNatives();    }        // 线程名字    private volatile String name;    private int            priority;    private Thread         threadQ;    private long           eetop;        // ...省略    }
复制代码


测试:



抽象实现


首先实现线程工厂构造器,主要构造线程工厂对象


@Getterpublic class ThreadFactoryBuilder {        private String nameFormat;
public ThreadFactoryBuilder setNameFormat(String nameFormat) { this.nameFormat = nameFormat; return this; }
public ThreadFactory build(){ return buildThreadFactory(this); }
public static ThreadFactory buildThreadFactory(ThreadFactoryBuilder builder) { final AtomicInteger counter = new AtomicInteger(0); return r -> { Thread t = new Thread(r); // 这里设置了线程池名称,使用counter区分不同线程 t.setName(String.format(builder.getNameFormat(), counter.getAndIncrement())); return t; }; }}
复制代码


查看源码 ExecutorService 源码,发现预留了线程工厂的入参


// ExecutorService newFixedThreadPool 预留了ThreadFactorypublic static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {    return new ThreadPoolExecutor(nThreads, nThreads,                                  0L, TimeUnit.MILLISECONDS,                                  new LinkedBlockingQueue<Runnable>(),                                  threadFactory);}
复制代码


测试代码正确性:


ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("测试命名线程-%d").build();ExecutorService executor = Executors.newFixedThreadPool(5, threadFactory);
for (int i = 0; i < 10; i++) { executor.execute(() -> { try { sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println(Thread.currentThread().getName()); });}
// 测试命名线程-3// 测试命名线程-2// 测试命名线程-1// 测试命名线程-0// 测试命名线程-4// 测试命名线程-0// 测试命名线程-2// 测试命名线程-1// 测试命名线程-3// 测试命名线程-4
复制代码


文章转载自:帅气的涛啊

原文链接:https://www.cnblogs.com/handsometaoa/p/18607435

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
Java线程命名问题解决_Java_快乐非自愿限量之名_InfoQ写作社区