因为多线程是程序单独的在另一个线程里执行,这样出现了异常我们的主线程是监测不到的。有时候我们希望当程序发生异常时,还能再去进行重试,当达到重试次数后在进行异常的处理。
首先我们定义一个回调接口,类似于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标签
相关推荐
例如,`WindowsApplication31`可能是一个简单的控制台应用程序,用于展示如何使用自定义线程池,而`TheadPooling`可能是实现线程池功能的核心类库。 自定义线程池的实现通常会包括以下步骤: 1. 初始化线程池:...
- **异常安全**:确保程序即使在出现异常的情况下也能正确释放资源。 - **错误传播**:确保错误能够在并发环境中被正确地捕获和传播。 #### 实际案例 通过具体的编程案例来学习并发编程的应用,例如: - **Web...
当定时任务抛出未捕获异常时,`Timer`会停止所有任务的执行。 - `ScheduledExecutorService`更为强大和安全,支持取消任务,可以创建多线程线程池,适合复杂的定时任务场景。 4. 扩展:Quartz Scheduler 对于更复杂...
循环定时任务,即任务会按照设定的时间间隔持续重复执行。 二、定时任务的实现原理 1. **Java的Timer类**:Timer类是Java基础库中的一个工具类,它允许开发者安排任务在未来某个时刻运行或定期执行。通过创建Timer...
- **活锁**:线程不断重复尝试执行某个操作,但始终没有进展。 #### 5.2 性能优化 - **减少锁的竞争**:使用细粒度锁或无锁编程。 - **减少上下文切换**:合理使用线程池,减少线程创建的数量。 ### 六、并发工具...
- 重复执行:可以设置任务每隔一定的时间间隔重复执行,如每分钟、每小时等。 - CRON表达式:使用CronTrigger,开发者可以利用CRON语法定义如“每天工作日的9点整”这样的执行规则。 4. **集群支持**: - 高可用...
- 异常是指在程序执行期间发生的事件,这种事件可能打断程序的正常执行流程。 - 当程序遇到问题时(例如,除以零、文件不存在等),会创建一个异常对象来表示这个错误,并传递给运行环境。这一过程被称为**抛出...
- **多态**:同一方法名可以在不同的类中实现不同的功能。 - **final, finally, finalize的区别**: - **final**:用于声明常量或方法不可更改。 - **finally**:在try-catch-finally结构中用于确保无论是否发生...
线程池是Java中一种高效的线程管理工具,它的出现是为了优化线程的创建和销毁过程,因为这两个操作在实际应用中可能会消耗大量资源。线程池通过预先创建一定数量的线程,使得任务能够迅速分配到线程上执行,从而提高...
此外,`scheduleAtFixedRate(TimerTask task, Date firstTime, long period)`和`scheduleAtFixedRate(TimerTask task, long initialDelay, long period)`则用于按固定速率重复执行任务。 2. java.util.concurrent....
- try-catch-finally:基本的异常处理结构,try块中可能出现异常的代码,catch块捕获并处理异常,finally块确保关键代码被执行。 - 自定义异常:可以通过创建新的类来扩展`Exception`类或其子类,定义自定义异常。...
- 通过实现`org.quartz.Job`接口中的`execute()`方法,你可以处理Job执行期间可能出现的异常。 - `MisfireInstruction`允许你指定当Trigger错过触发时间时应如何处理。 9. **最佳实践** - 尽可能使用无状态Job,...
- 对象通过类创建,通过调用类中的方法或设置类中的属性来实现功能。 - **封装、继承和多态**: - 封装是指将数据和操作这些数据的方法绑定在一起,并对外部隐藏内部实现细节。 - 继承允许子类继承父类的属性和...
- **替代方案:** 可以使用break和continue等关键字来实现类似的功能。 **3. 说说&&与&的区别?** - **逻辑运算符&&:** 表示逻辑与操作,短路运算。如果第一个表达式为false,则第二个表达式不会被计算。 - **位...
- 抽象类主要用于实现部分功能,接口用于定义行为规范。 13. **String、StringBuffer、StringBuilder的区别** - `String`是不可变的字符序列,适合少量的字符串操作。 - `StringBuffer`和`StringBuilder`都是可...
- `spider.py`:爬虫的主文件,负责启动和管理线程,可能包括URL队列、线程池等实现。 - `models.py`:可能定义了爬取的数据模型,用于存储和处理抓取到的信息。 - `utils.py`:可能包含了各种辅助工具函数,如请求...
`ThreadPoolExecutor`是Java提供的线程池实现之一,它具有丰富的配置项来满足不同场景的需求。 - **corePoolSize**:线程池的核心线程数。即使没有任务执行,这些线程也会一直存活。 - **maximumPoolSize**:线程池...
- **可重复读**(Repeatable Read):一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。 - **串行化**(Serializable):最高级别的隔离级别,完全解决了脏读、不可重复读和幻读的问题。...
- 指那些在异常情况下才会执行的代码。 - **5.1.1 异常退出幽灵代码导致的资源泄漏** - 如果异常处理不当,可能导致资源未被正确关闭。 - **5.2 wait()与循环** - 在等待条件满足时,使用`wait()`而不是忙等待循环,...