1. 构建一个线程池管理的工具类:ThreadManager
package com.example.design.thread;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 线程池管理的工具类:ThreadManager
*/
public class ThreadManager {
//通过ThreadPoolExecutor的代理类来对线程池的管理
private static ThreadPollProxy mThreadPollProxy; //单例对象
public static ThreadPollProxy getThreadPollProxy() {
synchronized (ThreadPollProxy.class) {
if (mThreadPollProxy == null) {
mThreadPollProxy = new ThreadPollProxy(3, 6, 1000);
}
}
return mThreadPollProxy;
}
//通过ThreadPoolExecutor的代理类来对线程池的管理
public static class ThreadPollProxy {
//线程池执行者, java内部通过该api实现对线程池管理
private ThreadPoolExecutor poolExecutor;
private int corePoolSize;
private int maximumPoolSize;
private long keepAliveTime;
ThreadPollProxy(int corePoolSize, int maximumPoolSize, long keepAliveTime) {
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.keepAliveTime = keepAliveTime;
} //对外提供一个执行任务的方法
public void execute(Runnable r) {
if (poolExecutor == null || poolExecutor.isShutdown()) {
ThreadFactory namedThreadFactory = new ThreadFactory() {
final AtomicInteger threadNumber = new AtomicInteger(1);
public Thread newThread(Runnable r) {
Thread t = new Thread(Thread.currentThread().getThreadGroup(), r, "topPatternTasklet-thread"
+ (threadNumber.getAndIncrement()));
t.setUncaughtExceptionHandler(new MyHandler());
return t;
}
};
BlockingQueue<Runnable> workingQueue = new ArrayBlockingQueue<>(1024);
RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
poolExecutor = new ThreadPoolExecutor(
//核心线程数量
corePoolSize,
//最大线程数量
maximumPoolSize,
//当线程空闲时,保持活跃的时间
keepAliveTime, //时间单元 ,
// 毫秒级
TimeUnit.MILLISECONDS,
//线程任务队列
workingQueue,
//创建线程的工厂
namedThreadFactory,
// 拒绝策略
rejectedExecutionHandler);
}
/**
* execute和submit的区别与联系:https://www.cnblogs.com/jpfss/p/11192220.html
* (1)execute和submit都属于线程池的方法,execute只能提交Runnable类型的任务,而submit既能提交Runnable类型任务也能提交Callable类型任务。
* (2)execute会直接抛出任务执行时的异常,submit会吃掉异常,可通过Future的get方法将任务执行时的异常重新抛出。
* (3)execute所属顶层接口是Executor,submit所属顶层接口是ExecutorService,实现类ThreadPoolExecutor重写了execute方法,抽象类AbstractExecutorService重写了submit方法。
*/
poolExecutor.execute(r);
}
}
}
2. 异常处理类:UncaughtExceptionHandler
package com.example.design.thread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 相关链接:https://www.cnblogs.com/wang-meng/p/10639914.html
*/
public class MyHandler implements Thread.UncaughtExceptionHandler {
private final static Logger LOGGER = LoggerFactory.getLogger(MyHandler.class);
@Override
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error("threadId = {}, threadName = {}, ex = {}", t.getId(), t.getName(), e.getMessage());
}
}
3. 执行子任务SubThread
package com.example.design.thread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SubThread implements Runnable {
private final static Logger LOGGER = LoggerFactory.getLogger(SubThread.class);
@Override
public void run() {
int count = 0;
while (true) {
count++;
LOGGER.info("-------222-------------{}", count);
if (count == 10) {
System.out.println(1 / 0);
try {
} catch (Exception e) {
LOGGER.error("Exception",e);
}
}
if (count == 20) {
LOGGER.info("count={}", count);
break;
}
}
}
}
4. 测试类
package com.example.design;
import com.example.design.thread.SubThread;
import com.example.design.thread.ThreadManager;
public class ThreadUtilsTest {
public static void main(String[] args) throws Exception {
ThreadManager.getThreadPollProxy().execute(new SubThread());
}
}