线程池:
简单理解,就是一个管理线程的池子。
线程池的创建:
线程池可以通过ThreadpoolExecutor来创建:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
几个核心参数的作用:
任务执行:
四种拒绝策略:
线程池异常处理:
在使用线程池处理任务的时候,任务代码可能抛出RuntimeException,抛出异常后,线程池可能捕获它,也可能创建一个新的线程来代替异常的线程,我们可能无法感知任务出现了异常,因此我们需要考虑线程池异常情况。
ExecutorService executorService=Executors.newFixedThreadPool(6); for (int i = 0; i < 6; i++) { executorService.submit(()->{ System.out.println("current thread name"+Thread.currentThread().getName()); try { Object object=null; System.out.println("result"+object.toString()); }catch (Exception e){ System.out.println("program occur"+e); } }); }
看下源码:
/** * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); execute(ftask); return ftask; } protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { return new FutureTask<T>(runnable, value); } public FutureTask(Runnable runnable, V result) { this.callable = Executors.callable(runnable, result); this.state = NEW; // ensure visibility of callable } public static <T> Callable<T> callable(Runnable task, T result) { if (task == null) throw new NullPointerException(); return new RunnableAdapter<T>(task, result); }
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command); }
public void run() { if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }
通过以上分析,submit执行的任务,可以通过Future对象的get()方法接收抛出的异常,再进行处理。因此可以通过future.get()来对异常进行处理。
public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(6); for (int i = 0; i < 6; i++) { Future future = executorService.submit(() -> { System.out.println("current thread name" + Thread.currentThread().getName()); Object object = null; System.out.println("result" + object.toString()); }); try { future.get(); } catch (Exception e) { System.out.println("program occur" + e); } } }
因此可以处理异常:
1. 在任务代码try/catch进行异常捕获。
2. 通过Future对象的get方法抛出异常,再进行捕获。
3. 为工作者线程设置UncaughtExceptionHandler,在方法中处理异常。
public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(6, t -> { Thread thread = new Thread(t); thread.setUncaughtExceptionHandler((thread1, e) -> { System.out.println(thread1.getName() + " occur:" + e); }); return thread; }); for (int i = 0; i < 8; i++) { executorService.execute(() -> { Object object = null; System.out.println("result" + object.toString()); }); } }
原文:https://www.cnblogs.com/award/p/11449567.html