线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池可以事先创建多个线程,等待着CPU分配执行任务,执行完之后返回池中等待下一次任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度,优化资源的使用。
public class Executor1 { public static void main(String[] args) { // ExecutorService service = Executors.newSingleThreadExecutor(); // 创建单个线程 // ExecutorService service = Executors.newFixedThreadPool(3); // 创建固定线程数的线程池 ExecutorService service = Executors.newCachedThreadPool(); // 可变数量线程数的线程池 try { for (int i = 1; i <= 15; i++) { service.execute(()->{ System.out.println(Thread.currentThread().getName()+" start"); }); } } catch (Exception e) { e.printStackTrace(); } finally { service.shutdown(); } } }
自定义线程池
public class Threadpool { public static void main(String[] args) { /* 拒绝策略 AbortPolicy() 被拒绝的任务的处理程序,抛出一个 RejectedExecutionException CallerRunsPolicy() 一个被拒绝的任务的处理程序,直接在 execute方法的调用线程中运行被拒绝的任务,除非执行程序已经被关闭,否则这个任务被丢弃 DiscardOldestPolicy() 被拒绝的任务的处理程序,丢弃最旧的未处理请求,然后重试 execute ,除非执行程序关闭,在这种情况下,任务被丢弃 DiscardPolicy() 被拒绝的任务的处理程序静默地丢弃被拒绝的任务 */ ExecutorService service = new ThreadPoolExecutor( 2,//核心线程数 6,//最大线程数 3,//等待时间 TimeUnit.SECONDS,//时间单位 new ArrayBlockingQueue<>(3),//阻塞队列 Executors.defaultThreadFactory(),//默认的线程工厂 new ThreadPoolExecutor.DiscardOldestPolicy() ); try { for (int i = 1; i <= 15; i++) { service.execute(()->{ System.out.println(Thread.currentThread().getName()+" start"); }); } } catch (Exception e) { e.printStackTrace(); } finally { service.shutdown(); } } }
获取CPU核数:
Runtime.getRuntime().availableProcessors()