并发编程系列之自定义可以命名的线程池工厂类

x33g5p2x  于2021-12-13 转载在 其他  
字(3.5k)|赞(0)|评价(0)|浏览(524)

在使用多线程时候,有时候需要记录具体是哪些业务执行的,不过按照默认的情况,是会打印pool-1-thread-1这种类型的数据,所以有时候不能确定具体哪些业务线程执行的,可以先写一个线程池sample类,运行看看情况:

  1. import java.util.concurrent.ArrayBlockingQueue;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.ThreadPoolExecutor;
  4. import java.util.concurrent.TimeUnit;
  5. public class ThreadPoolExample {
  6. public static void main(String[] args) {
  7. ExecutorService orderThreadPool = new ThreadPoolExecutor(2, 5,
  8. 60L, TimeUnit.SECONDS,
  9. new ArrayBlockingQueue(5));
  10. ExecutorService sendThreadPool = new ThreadPoolExecutor(2, 5,
  11. 60L, TimeUnit.SECONDS,
  12. new ArrayBlockingQueue(5));
  13. orderThreadPool.execute(new OrderTask());
  14. sendThreadPool.execute(new SendTask());
  15. // 避免内存泄露,记得关闭线程池
  16. orderThreadPool.shutdown();
  17. sendThreadPool.shutdown();
  18. }
  19. static class OrderTask implements Runnable {
  20. @Override
  21. public void run() {
  22. System.out.println(String.format("thread name:%s",Thread.currentThread().getName()));
  23. System.out.println("保存订单信息");
  24. }
  25. }
  26. static class SendTask implements Runnable {
  27. @Override
  28. public void run() {
  29. System.out.println(String.format("thread name:%s",Thread.currentThread().getName()));
  30. System.out.println("保存发货信息");
  31. }
  32. }
  33. }

控制台打印,不能定位是哪些线程

跟一下源码:

  1. public ThreadPoolExecutor(int corePoolSize,
  2. int maximumPoolSize,
  3. long keepAliveTime,
  4. TimeUnit unit,
  5. BlockingQueue<Runnable> workQueue) {
  6. this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
  7. Executors.defaultThreadFactory(), defaultHandler);
  8. }

默认使用了线程池工厂类

  1. public static ThreadFactory defaultThreadFactory() {
  2. return new DefaultThreadFactory();
  3. }

默认的线程池工厂,namePrefix = "pool-" +poolNumber.getAndIncrement() + "-thread-";,使用一个原子类,命名规则是这样的

  1. /** * The default thread factory */
  2. static class DefaultThreadFactory implements ThreadFactory {
  3. private static final AtomicInteger poolNumber = new AtomicInteger(1);
  4. private final ThreadGroup group;
  5. private final AtomicInteger threadNumber = new AtomicInteger(1);
  6. private final String namePrefix;
  7. DefaultThreadFactory() {
  8. SecurityManager s = System.getSecurityManager();
  9. group = (s != null) ? s.getThreadGroup() :
  10. Thread.currentThread().getThreadGroup();
  11. namePrefix = "pool-" +
  12. poolNumber.getAndIncrement() +
  13. "-thread-";
  14. }
  15. public Thread newThread(Runnable r) {
  16. Thread t = new Thread(group, r,
  17. namePrefix + threadNumber.getAndIncrement(),
  18. 0);
  19. if (t.isDaemon())
  20. t.setDaemon(false);
  21. if (t.getPriority() != Thread.NORM_PRIORITY)
  22. t.setPriority(Thread.NORM_PRIORITY);
  23. return t;
  24. }
  25. }

所以,这边简单改下代码,传一个自定义的name进去就行

  1. import org.springframework.util.StringUtils;
  2. import java.util.concurrent.ThreadFactory;
  3. import java.util.concurrent.atomic.AtomicInteger;
  4. public class NamedThreadFactory implements ThreadFactory {
  5. private static final AtomicInteger poolNumber = new AtomicInteger(1);
  6. /** 线程组 **/
  7. private final ThreadGroup group;
  8. /** 原子类保证计数线程安全 **/
  9. private final AtomicInteger threadNumber = new AtomicInteger(1);
  10. /** 命名前缀 **/
  11. private final String namePrefix;
  12. NamedThreadFactory(String threadFactoryName) {
  13. SecurityManager s = System.getSecurityManager();
  14. group = (s != null) ? s.getThreadGroup() :
  15. Thread.currentThread().getThreadGroup();
  16. threadFactoryName = StringUtils.isEmpty(threadFactoryName)
  17. ? "pool-"
  18. : threadFactoryName + "-";
  19. namePrefix = threadFactoryName + poolNumber.getAndIncrement()+ "-thread-";
  20. }
  21. @Override
  22. public Thread newThread(Runnable r) {
  23. Thread t = new Thread(group, r,
  24. namePrefix + threadNumber.getAndIncrement(),
  25. 0);
  26. // 守护线程
  27. if (t.isDaemon())
  28. t.setDaemon(false);
  29. // 优先级
  30. if (t.getPriority() != Thread.NORM_PRIORITY)
  31. // 标准优先级
  32. t.setPriority(Thread.NORM_PRIORITY);
  33. return t;
  34. }
  35. }

将自定义的NamedThreadFactory类传进去

  1. ExecutorService orderThreadPool = new ThreadPoolExecutor(2, 5,
  2. 60L, TimeUnit.SECONDS,
  3. new ArrayBlockingQueue(5),
  4. new NamedThreadFactory("orderPool"));

控制台打印

OK,例子是比较简单的,不过目的是通过例子,看看源码的实现原理

相关文章