ExecutorService的API详解
ExecutorService的终止方法
package com.dwz.executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.IntStream; /** * The demo for class {@link java.util.concurrent.ExecutorService} * * question: * When invoked the shutDown method, can execute the new runnable? * Answer: * No!! the ExecutorService will reject after shutDown */ public class ExecutorServiceExample1 { private static void isShutDown() { ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(executorService.isShutdown()); executorService.shutdown(); System.out.println(executorService.isShutdown()); executorService.execute(() -> System.out.println("I will be executed after shutDown ???")); } /** * {@link ExecutorService#isTerminated()} * {@link ThreadPoolExecutor#isTerminating()} */ private static void isTerminated() { ExecutorService executorService = Executors.newFixedThreadPool(1); executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } }); executorService.shutdown(); System.out.println(executorService.isShutdown()); System.out.println(executorService.isTerminated()); System.out.println(((ThreadPoolExecutor)executorService).isTerminating()); } private static void executeRunnableError() throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(10, new MyThreadFactory()); IntStream.range(0, 10).boxed().forEach(i -> executorService.execute(() -> System.out.println(1 / 0))); executorService.shutdown(); executorService.awaitTermination(10, TimeUnit.MINUTES); System.out.println("====================================="); } private static class MyThreadFactory implements ThreadFactory { private final static AtomicInteger SEQ = new AtomicInteger(); @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName("My-Thread-" + SEQ.getAndIncrement()); t.setUncaughtExceptionHandler((i, cause) -> { System.out.println("The thread " + i.getName() + " execute failed."); cause.printStackTrace(); System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); }); return t; } } //通过某种方式获取执行结果,即runnable的返回值 private abstract static class MyTask implements Runnable { protected final int no; public MyTask(int no) { this.no = no; } @Override public void run() { try { this.doInit(); this.doExecute(); this.done(); } catch (Throwable cause) { this.error(cause); } } protected abstract void error(Throwable cause); protected abstract void done(); protected abstract void doExecute(); protected abstract void doInit(); } /* * <pre> * |--->操作1 * |--->操作2 * send request-->store db-->10->|--->操作3-->给出不同的反馈 * |--->操作4 * |--->操作5 * </pre> */ private static void executeRunnableTask() throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(10, new MyThreadFactory()); IntStream.range(0, 10).boxed().forEach(i -> executorService.execute( new MyTask(i) { @Override protected void error(Throwable cause) { System.out.println("The no:" + i + " failed , update status to ERROR."); } @Override protected void done() { System.out.println("The no:" + i + " successfully , update status to DONE."); } @Override protected void doInit() { //do nothing } @Override protected void doExecute() { if(i % 3 == 0) { int tmp = 1 / 0; } } } )); executorService.shutdown(); executorService.awaitTermination(10, TimeUnit.MINUTES); System.out.println("====================================="); } public static void main(String[] args) throws InterruptedException { isShutDown(); isTerminated(); executeRunnableError(); executeRunnableTask(); } }
ExecutorService的各种策略
package com.dwz.executors; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ExecutorServiceExample2 { private static void testAbortPolicy() throws InterruptedException { ExecutorService executorService = new ThreadPoolExecutor(1, 2, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), r -> { Thread t = new Thread(r); return t; }, new ThreadPoolExecutor.AbortPolicy()); for(int i = 0; i < 3; i++) { executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } }); } //确保三个任务都已提交 TimeUnit.SECONDS.sleep(1); //执行第四个出错java.util.concurrent.RejectedExecutionException,因为最多可以同时执行三个线程 executorService.execute(() -> System.out.println("xxxxxxxxxx")); } //直接拒绝,没有任何异常抛出 private static void testDiscardPolicy() throws InterruptedException { ExecutorService executorService = new ThreadPoolExecutor(1, 2, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), r -> { Thread t = new Thread(r); return t; }, new ThreadPoolExecutor.DiscardPolicy()); for(int i = 0; i < 3; i++) { executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } }); } //确保三个任务都已提交 TimeUnit.SECONDS.sleep(1); executorService.execute(() -> System.out.println("xxxxxxxxxx")); System.out.println("======================"); } //把queue中的女任务抛弃,转而执行本应被拒绝的任务 private static void testDiscardOldestPolicy() throws InterruptedException { ExecutorService executorService = new ThreadPoolExecutor(1, 2, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), r -> { Thread t = new Thread(r); return t; }, new ThreadPoolExecutor.DiscardOldestPolicy()); for(int i = 0; i < 3; i++) { executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(5); System.out.println("I come from lambda."); } catch (InterruptedException e) { e.printStackTrace(); } }); } //确保三个任务都已提交 TimeUnit.SECONDS.sleep(1); executorService.execute(() -> { System.out.println("xxxxxxxxxxxxxxxxxxxxx"); System.out.println(Thread.currentThread().getName()); }); System.out.println("======================"); } //本来应该被拒绝的任务直接执行 private static void testCallerRunsPolicy() throws InterruptedException { ExecutorService executorService = new ThreadPoolExecutor(1, 2, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), r -> { Thread t = new Thread(r); return t; }, new ThreadPoolExecutor.CallerRunsPolicy()); for(int i = 0; i < 3; i++) { executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } }); } //确保三个任务都已提交 TimeUnit.SECONDS.sleep(1); executorService.execute(() -> { System.out.println("xxxxxxxxxxxxxxxxxxxxx"); System.out.println(Thread.currentThread().getName()); }); System.out.println("======================"); } public static void main(String[] args) throws InterruptedException { testAbortPolicy(); testDiscardPolicy(); testDiscardOldestPolicy(); testCallerRunsPolicy(); } }
ThreadPoolExecutor对CoreThread的操作
package com.dwz.executors; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; public class ExecutorServiceExample3 { private static void test() throws InterruptedException { ThreadPoolExecutor executorService = (ThreadPoolExecutor)Executors.newFixedThreadPool(5); System.out.println(executorService.getActiveCount()); executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } }); TimeUnit.MILLISECONDS.sleep(20); System.out.println(executorService.getActiveCount()); executorService.allowCoreThreadTimeOut(true); } private static void testAllowCoreThreadTimeOut() { ThreadPoolExecutor executorService = (ThreadPoolExecutor)Executors.newFixedThreadPool(5); executorService.setKeepAliveTime(10, TimeUnit.SECONDS); //为true时keepAliveTime的时间必须大于1 executorService.allowCoreThreadTimeOut(true); IntStream.range(0, 5).boxed().forEach(i -> { executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } }); }); } private static void testRemove() throws InterruptedException { ThreadPoolExecutor executorService = (ThreadPoolExecutor)Executors.newFixedThreadPool(2); executorService.setKeepAliveTime(10, TimeUnit.SECONDS); //为true时keepAliveTime的时间必须大于1 executorService.allowCoreThreadTimeOut(true); IntStream.range(0, 2).boxed().forEach(i -> { executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(5); System.out.println("================ I am finished."); } catch (InterruptedException e) { e.printStackTrace(); } }); }); TimeUnit.MILLISECONDS.sleep(20); Runnable r = () -> { System.out.println("I will never be executed."); }; executorService.execute(r); TimeUnit.MILLISECONDS.sleep(20); //将queue中的任务删除 executorService.remove(r); } private static void testPrestartCoreThread() { ThreadPoolExecutor executorService = (ThreadPoolExecutor)Executors.newFixedThreadPool(2); executorService.setMaximumPoolSize(3); System.out.println(executorService.getActiveCount()); int num = executorService.prestartAllCoreThreads(); System.out.println(num); System.out.println(executorService.getActiveCount()); // executorService.prestartCoreThread(); System.out.println(executorService.prestartCoreThread()); System.out.println(executorService.getActiveCount()); // executorService.prestartCoreThread(); System.out.println(executorService.prestartCoreThread()); executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } }); executorService.execute(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(executorService.getActiveCount()); // executorService.prestartCoreThread(); System.out.println(executorService.prestartCoreThread()); System.out.println(executorService.getActiveCount()); } //beforeExecute和afterExecute类似于切面 private static void testThreadPoolAdvice() { ThreadPoolExecutor executorService = new MyThreadPoolExecutor(1, 2, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), r -> { Thread t = new Thread(r); return t; }, new ThreadPoolExecutor.AbortPolicy()); executorService.execute(new MyRunnable(1) { @Override public void run() { System.out.println("================="); } }); } private abstract static class MyRunnable implements Runnable { private final int no; public MyRunnable(int no) { this.no = no; } protected int getData() { return this.no; } } private static class MyThreadPoolExecutor extends ThreadPoolExecutor { public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); } @Override protected void beforeExecute(Thread t, Runnable r) { System.out.println("init the " + ((MyRunnable)r).getData()); } @Override protected void afterExecute(Runnable r, Throwable t) { if(null == t) { System.out.println("successful " + ((MyRunnable)r).getData()); } else { t.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { test(); testAllowCoreThreadTimeOut(); testRemove(); testPrestartCoreThread(); testThreadPoolAdvice(); } }
ExecutorService的invoke和submit调用
package com.dwz.executors; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; import java.util.stream.IntStream; public class ExecutorServiceExample4 { /** * Question: * When the result returned, other callable will be keep on process? * Answer: * Other executing Callable will be canceled. * {@link ExecutorService#invokeAny(Collection)} */ private static void testInvokeAny() throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newFixedThreadPool(10); List<Callable<Integer>> callableList = IntStream.range(0, 5).boxed().map( i -> (Callable<Integer>) () -> { TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(20)); System.out.println(Thread.currentThread().getName() + " :" + i); return i; } ).collect(Collectors.toList()); //这是一个同步方法,执行完成后才会执行后面的任务 Integer value = executorService.invokeAny(callableList); System.out.println("===================finished====================="); System.out.println(value); } /** * timeout 异常之后其他正在执行的任务会被取消 * {@link ExecutorService#invokeAny(java.util.Collection, long, TimeUnit)} */ private static void testInvokeAnyTimeOut() throws InterruptedException, ExecutionException, TimeoutException { ExecutorService executorService = Executors.newFixedThreadPool(10); List<Callable<Integer>> callableList = IntStream.range(0, 5).boxed().map( i -> (Callable<Integer>) () -> { TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(20)); System.out.println(Thread.currentThread().getName() + " :" + i); return i; } ).collect(Collectors.toList()); //这是一个同步方法,执行完成后才会执行后面的任务 Integer value = executorService.invokeAny(callableList, 3, TimeUnit.SECONDS); System.out.println("===================finished====================="); System.out.println(value); } /** * {@link ExecutorService#invokeAny(java.util.Collection)} */ private static void testInvokeAll() throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(10); //这是一个同步方法,执行完成后才会执行后面的任务 executorService.invokeAll( IntStream.range(0, 5).boxed().map( i -> (Callable<Integer>) () -> { TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(20)); System.out.println(Thread.currentThread().getName() + " :" + i); return i; } ).collect(Collectors.toList()) ).stream().map(future -> { try { return future.get(); } catch (Exception e) { throw new RuntimeException(); } }).forEach(System.out::println); System.out.println("===================finished====================="); } /** * {@link ExecutorService#invokeAny(java.util.Collection, long, TimeUnit)} */ private static void testInvokeAllTimeOut() throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(10); //这是一个同步方法,执行完成后才会执行后面的任务 executorService.invokeAll( IntStream.range(0, 5).boxed().map( i -> (Callable<Integer>) () -> { TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(20)); System.out.println(Thread.currentThread().getName() + " :" + i); return i; } ).collect(Collectors.toList()), 1, TimeUnit.SECONDS ).stream().map(future -> { try { return future.get(); } catch (Exception e) { throw new RuntimeException(); } }).forEach(System.out::println); System.out.println("===================finished====================="); } /** * {@link ExecutorService#submit(Runnable)} */ private static void testSubmitRunnable() throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newFixedThreadPool(10); Future<?> future = executorService.submit(() -> { try { TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }); //get()会产生阻塞,等待前面的任务执行完 Object NULL = future.get(); System.out.println("R:" + NULL); } /** * {@link ExecutorService#submit(Runnable, Object)} */ private static void testSubmitRunnableWithResult() throws InterruptedException, ExecutionException { ExecutorService executorService = Executors.newFixedThreadPool(10); String result = "DONE"; Future<String> future = executorService.submit(() -> { try { TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } }, result); result = future.get(); System.out.println("R:" + result); } public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException { testInvokeAny(); testInvokeAnyTimeOut(); testInvokeAll(); testInvokeAllTimeOut(); testSubmitRunnable(); testSubmitRunnableWithResult(); } }
问题:直接把任务加到queue中会不会被执行?
答案:1.在不执行execute()、submit()、invoke()等方法的前提下是不会执行该任务的,因为不会触发线程创建来执行该任务
2.反之可以
package com.dwz.executors; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; public class ExecutorServiceExample5 { public static void main(String[] args) { ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5); threadPoolExecutor.execute(() -> System.out.println("I will be process because of triggered the execute.")); threadPoolExecutor.getQueue().add(() -> { System.out.println("I am added direcyly into the queue."); }); } }