ThreadPoolExecutor executor = new ThreadPoolExecutor(2, //核心线程数 5,//最大线程数 60L, //临时线程空闲时间 TimeUnit.SECONDS,//时间单位 new ArrayBlockingQueue<Runnable>(25), //线程池任务队列 new ThreadPoolExecutor.CallerRunsPolicy());//任务超出线程池能力异常处理
线程池手动创建方法如上所示,
核心线程数表示当线程池有任务进来时,会创建线程处理任务,最大不能超过这个数值,并且空闲时不会被释放;
最大线程数表示当核心线程数被占用,并且队列任务装满之后,会临时开启线程来处理后续加入的任务,临时线程最大数量 = 最大线程数-核心线程数;
临时线程空闲时间表示临时线程最大空闲时间,超过这个时间后,临时线程会释放
线程池任务队列表示当核心线程都被占用时,后续任务会被添加进队列中等待,等核心进程空闲时,会拿取队列中的任务进行处理。当队列装满后,会创建临时线程处理任务。
异常处理作用是当线程池任务队列装满,并且最大线程数创建满且都在执行任务,后续再有任务进来时,线程池会将任务交给异常处理消化
当需要线程池处理完事件,再回到主线程执行是,可以使用CountDownLatch让主线程阻塞,当CountDownLatch配置的任务数执行完成后,主线程再被唤醒
public static void test(boolean flag) { System.out.println("开启线程池"); ThreadPoolExecutor executor = new ThreadPoolExecutor(5, //活动线程数 5,//最大线程数 60L, //临时线程空闲时间 TimeUnit.SECONDS,//时间单位 new ArrayBlockingQueue<>(30), //线程池任务队列 new ThreadPoolExecutor.CallerRunsPolicy());//任务超出线程池能力异常处理 executor.allowCoreThreadTimeOut(true); int forCounts = 30; CountDownLatch countd = new CountDownLatch(forCounts);// 线程池优先执行的计时器 syncSubmit1(executor, countd, forCounts); try { countd.await(); } catch (InterruptedException e) { e.printStackTrace(); } syso(Thread.currentThread().getName()); //优雅释放线程池,等待线程池中正在执行任务的线程执行完后再进行释放 executor.shutdownNow(); //强制释放线程池,所有线程(包含正在执行任务的线程)立即停止并释放 //executor.shutdown(); while (true) { if (executor.isShutdown()) { syso("线程池释放了"); System.exit(0); } else { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } syso("线程池没有释放"); } } } private static void syncSubmit1(ThreadPoolExecutor executor, CountDownLatch countd, int forCounts) { for (int i = 0; i < forCounts; i++) { executor.submit(new MyThread1(i, countd)); } } static class MyThread1 implements Runnable { int i; CountDownLatch countd; public MyThread1(int i, CountDownLatch countd) { this.i = i; this.countd = countd; } @Override public void run() { if (countd.getCount() != 0) { syso(" i = " + i + ",ThreadPoolExecutor'run's thread name = " + Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } countd.countDown(); } }
代码执行结果:
开启线程池 i = 1,ThreadPoolExecutor'run's thread name = pool-1-thread-2 i = 0,ThreadPoolExecutor'run's thread name = pool-1-thread-1 i = 2,ThreadPoolExecutor'run's thread name = pool-1-thread-3 i = 3,ThreadPoolExecutor'run's thread name = pool-1-thread-4 i = 4,ThreadPoolExecutor'run's thread name = pool-1-thread-5 i = 5,ThreadPoolExecutor'run's thread name = pool-1-thread-1 i = 8,ThreadPoolExecutor'run's thread name = pool-1-thread-5 i = 7,ThreadPoolExecutor'run's thread name = pool-1-thread-2 i = 6,ThreadPoolExecutor'run's thread name = pool-1-thread-3 i = 9,ThreadPoolExecutor'run's thread name = pool-1-thread-4 i = 10,ThreadPoolExecutor'run's thread name = pool-1-thread-2 i = 14,ThreadPoolExecutor'run's thread name = pool-1-thread-4 i = 11,ThreadPoolExecutor'run's thread name = pool-1-thread-1 i = 13,ThreadPoolExecutor'run's thread name = pool-1-thread-3 i = 12,ThreadPoolExecutor'run's thread name = pool-1-thread-5 i = 15,ThreadPoolExecutor'run's thread name = pool-1-thread-4 i = 19,ThreadPoolExecutor'run's thread name = pool-1-thread-1 i = 18,ThreadPoolExecutor'run's thread name = pool-1-thread-3 i = 16,ThreadPoolExecutor'run's thread name = pool-1-thread-5 i = 17,ThreadPoolExecutor'run's thread name = pool-1-thread-2 i = 20,ThreadPoolExecutor'run's thread name = pool-1-thread-2 i = 24,ThreadPoolExecutor'run's thread name = pool-1-thread-1 i = 23,ThreadPoolExecutor'run's thread name = pool-1-thread-3 i = 22,ThreadPoolExecutor'run's thread name = pool-1-thread-5 i = 21,ThreadPoolExecutor'run's thread name = pool-1-thread-4 i = 25,ThreadPoolExecutor'run's thread name = pool-1-thread-5 i = 27,ThreadPoolExecutor'run's thread name = pool-1-thread-1 i = 28,ThreadPoolExecutor'run's thread name = pool-1-thread-2 i = 29,ThreadPoolExecutor'run's thread name = pool-1-thread-4 i = 26,ThreadPoolExecutor'run's thread name = pool-1-thread-3 main 线程池释放了
以上是线程池的基本使用,还有很多其他用法,慢慢研究吧