线程池
线程池的7大参数:
核心线程数、最大线程数、线程空闲存活时间、时间单位、阻塞队列、线程工厂、抛弃策略
线程池的执行流程:
当线程池中的线程数小于核心线程数时,创建核心线程执行任务;
当核心线程数满了之后,看阻塞队列是否存储满了,未满,就将任务放到阻塞队列中;
当阻塞队列满了之后,看是否达到了最大线程数,如果未达到最大线程数,则创建线程来执行;
如果达到了最大线程数,则执行抛弃策略
线程池的抛弃策略有哪些?
1)直接丢弃
2)丢弃并抛出异常
3)丢弃阻塞队列中最前面的任务
4)让提交任务的线程来执行此任务
常用的线程池有哪些?
都是 ThreadPoolExecutor来实现的。
1)单线程的线程池
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
2)固定数量的线程池
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
3)
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
4)
public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
为什么使用这些线程池会出现OOM异常?
因为它们的阻塞队列的容量大小都是用的 Integer.MAX_VALUE
线程池的线程数如何选取?
这个要根据处理的业务是CPU密集型 还是 IO密集型来确定。
1)对于CPU密集型,就是进行大量的运算,CPU一直在运行,这种情况设置线程池中线程的数量和CPU的核数差不多就可以。因为配置多了,运算时间不会降低,反而线程来回切换的耗时,还提高了总的运算时间
2)IO密集型 这种情况会经常发生线程的阻塞,因此配置的线程数要多一点。
线程池的好处:
1)线程的创建和销毁都会消耗资源和时间,使用线程池,减少了资源的消耗,提高了响应速度,而且可以更好的集中管理线程。
也许会有遗憾,但是不应该在失败之前
浙公网安备 33010602011771号