在使用多线程时候,有时候需要记录具体是哪些业务执行的,不过按照默认的情况,是会打印pool-1-thread-1
这种类型的数据,所以有时候不能确定具体哪些业务线程执行的,可以先写一个线程池sample类,运行看看情况:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService orderThreadPool = new ThreadPoolExecutor(2, 5,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(5));
ExecutorService sendThreadPool = new ThreadPoolExecutor(2, 5,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(5));
orderThreadPool.execute(new OrderTask());
sendThreadPool.execute(new SendTask());
// 避免内存泄露,记得关闭线程池
orderThreadPool.shutdown();
sendThreadPool.shutdown();
}
static class OrderTask implements Runnable {
@Override
public void run() {
System.out.println(String.format("thread name:%s",Thread.currentThread().getName()));
System.out.println("保存订单信息");
}
}
static class SendTask implements Runnable {
@Override
public void run() {
System.out.println(String.format("thread name:%s",Thread.currentThread().getName()));
System.out.println("保存发货信息");
}
}
}
控制台打印,不能定位是哪些线程
thread name:pool-1-thread-1 保存订单信息 thread name:pool-2-thread-1 保存发货信息
跟一下源码:
代码语言:javascript复制public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
默认使用了线程池工厂类
代码语言:javascript复制public static ThreadFactory defaultThreadFactory() {
return new DefaultThreadFactory();
}
默认的线程池工厂,namePrefix = "pool-" poolNumber.getAndIncrement() "-thread-";
,使用一个原子类,命名规则是这样的
/**
* The default thread factory
*/
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;
}
}
所以,这边简单改下代码,传一个自定义的name进去就行
代码语言:javascript复制import org.springframework.util.StringUtils;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
public class NamedThreadFactory 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;
NamedThreadFactory(String threadFactoryName) {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
threadFactoryName = StringUtils.isEmpty(threadFactoryName)
? "pool-"
: threadFactoryName "-";
namePrefix = threadFactoryName poolNumber.getAndIncrement() "-thread-";
}
@Override
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;
}
}
将自定义的NamedThreadFactory
类传进去
ExecutorService orderThreadPool = new ThreadPoolExecutor(2, 5,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue(5),
new NamedThreadFactory("orderPool"));
控制台打印
thread name:sendPool-2-thread-1 保存发货信息 thread name:orderPool-1-thread-1 保存订单信息
OK,例子是比较简单的,不过目的是通过例子,看看源码的实现原理