先来看一段代码
public class ThreadMain {
private static class SimpleThreadFactory implements ThreadFactory {
private static final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
public SimpleThreadFactory() {
namePrefix = "simple-pool-thread-";
}
public Thread newThread(Runnable r) {
int i = threadNumber.getAndIncrement();
return new Thread(namePrefix + i);
}
}
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
ExecutorService executorService = new ThreadPoolExecutor(1, 1, 60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10), new SimpleThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
executorService.submit(() -> {
try {
System.out.println("worker done");
} catch (Throwable e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
countDownLatch.await();
System.out.println("main done");
executorService.shutdown();
}
}
很简单的一段代码,main方法中用ThreadPoolExecutor
定义了一个线程池,用CountDownLatch做同步,主线程在工作线程打印出worker done
后,打印main done
并退出。实际运行,发现控制台没有任何输出。问题出在哪呢?
经过分析可知,工作线程没有执行任务,countDownLatch
没有计数,于是主线程阻塞了,可为什么任务不执行呢?
直接揭晓结果,看这段代码:
public Thread newThread(Runnable r) {
int i = threadNumber.getAndIncrement();
return new Thread(namePrefix + i);
}
SimpleThreadFactory
类实现ThreadFactory
,用于自定义自己的线程工厂,需要实现newThread
方法,其他有个Runnable类型的参数r,上面这段代码没有用到这个参数,被初始化的线程中待执行的任务为空,看下面这段Thread类中的代码:
@Override
public void run() {
if (target != null) {
target.run();
}
}
target对应上面newThread
方法中的参数r,那就明白了:线程池中初始化了一个线程,但这个线程没有任务,那任务自然不能被执行,打印任务不能完成,修改后的代码如下:
public Thread newThread(Runnable r) {
int i = threadNumber.getAndIncrement();
return new Thread(r, namePrefix + i);
}
之后程序可以正常运行退出