因为多线程是程序单独的在另一个线程里执行,这样出现了异常我们的主线程是监测不到的。有时候我们希望当程序发生异常时,还能再去进行重试,当达到重试次数后在进行异常的处理。
首先我们定义一个回调接口,类似于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标签