面试题答案
一键面试-
自定义任务类:
- 首先,创建不同类型任务的自定义类,让它们实现
Runnable
或Callable
接口。例如:
class SpecialTask implements Callable<Integer> { @Override public Integer call() throws Exception { // 任务逻辑 if (someCondition) { throw new SpecialTaskException(); } return result; } }
- 这里
SpecialTaskException
是自定义的针对这种特殊任务的异常类型。
- 首先,创建不同类型任务的自定义类,让它们实现
-
自定义线程池:
- 使用
ThreadPoolExecutor
来创建线程池。可以通过继承ThreadPoolExecutor
并重写afterExecute
方法来处理任务执行后的异常。
class CustomThreadPool extends ThreadPoolExecutor { public CustomThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (t != null) { if (r instanceof SpecialTask) { handleSpecialTaskException(t); } else { handleGeneralException(t); } } } private void handleSpecialTaskException(Throwable t) { // 处理特殊任务异常的逻辑 System.err.println("Special task exception: " + t.getMessage()); // 可以进行日志记录、报警等操作 } private void handleGeneralException(Throwable t) { // 处理一般任务异常的逻辑 System.err.println("General task exception: " + t.getMessage()); // 可以进行日志记录、报警等操作 } }
- 使用
-
使用自定义线程池:
- 在项目中使用自定义的线程池来提交任务。
CustomThreadPool executor = new CustomThreadPool( 5, 10, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); Future<Integer> future = executor.submit(new SpecialTask()); try { Integer result = future.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
- 这样,通过自定义线程池的
afterExecute
方法,我们可以在任务执行完毕后,根据任务类型来处理不同的异常,并且不会影响其他任务的正常执行。每个任务的异常处理逻辑是相互独立的,线程池会继续处理队列中的其他任务。