因为多线程是程序单独的在另一个线程里执行,这样出现了异常我们的主线程是监测不到的。有时候我们希望当程序发生异常时,还能再去进行重试,当达到重试次数后在进行异常的处理。
首先我们定义一个回调接口,类似于Runnable接口,如下:
public interface QltRunnable{
/**
* 程序正常的执行逻辑
*/
void run() ;
/**
* 当达到最大重试次数后异常的处理逻辑
*/
void error(Exception e) ;
}
然后我们定义我们自己的线程池对象,如下:
public class QltThreadPoolExecutor{
private ThreadPoolExecutor threadPoolExecutor;
//重试次数
private int retry=3;
//线程池大小
private int size=1;
public QltThreadPoolExecutor(){
//无参构造方法 默认线程数大小为电脑的核心数
this(Runtime.getRuntime().availableProcessors());
}
public QltThreadPoolExecutor(int threadCount){
this.size=threadCount;
threadPoolExecutor= (ThreadPoolExecutor) Executors.newFixedThreadPool(threadCount);
}
/**
* 对外暴露的可执行的方法
* @param runnable
*/
public void execute(final QltRunnable runnable){
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
execute(runnable,0);
}
});
}
private void execute(final QltRunnable runnable, int retryCount){
try {
runnable.run();
}catch (Exception e){
//如果小于重试次数,则进行重试
if(retryCount<retry){
execute(runnable,++retryCount);
}else{
//超过设置的重试次数 则进行异常处理
runnable.error(e);
}
}
}
public ThreadPoolExecutor getThreadPoolExecutor() {
return threadPoolExecutor;
}
public int getRetry() {
return retry;
}
public void setRetry(int retry) {
this.retry = retry;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
threadPoolExecutor.setCorePoolSize(size);
threadPoolExecutor.setMaximumPoolSize(size);
}
}
现在我们的功能就实现了,实现的非常的简单,用起来也很简单。
1、可以手动的去new一个使用,如下:
//线程数设置为5
QltThreadPoolExecutor executor=new QltThreadPoolExecutor(5);
//开启一个线程
executor.execute(new QltRunnable() {
@Override
public void run() {
int i=6/0;
}
@Override
public void error(Exception e) {
System.out.println("出错了");
}
});
2、使用spring配置:
<bean class="cn.qlt.common.utils.concurrent.QltThreadPoolExecutor">
<!--线程池大小-->
<property name="size" value="10"/>
<!--重试次数-->
<property name="retry" value="5"/>
</bean>
然后在程序中我们将其注入即可。
总结:该功能的实现非常简单,即我们自定义了回调的对象。并结合java的线程池实现了该功能。但感觉spring的配置还略微麻烦,下面一节我们来自定义spring标签