1、线程池是什么
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。
2、线程池的优势
降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗
提高系统响应速度,当有任务到达时,通过复用已存在的线程,无需等待新线程的创建便能立即执行
方便线程并发数的管控。因为线程若是无限制的创建,可能会导致内存占用过多而产生OOM,并且会造成cpu过度切换(cpu切换线程是有时间成本的(需要保持当前执行线程的现场,并恢复要执行线程的现场))
提供更强大的功能,延时定时线程池
3、创建线程池
(1)Executors创建线程池
/** * 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程 队列无限长 */ @Test public void Test01() { ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) { newCachedThreadPool.execute(new Runnable() { public void run() { System.out.println(Thread.currentThread().getName()); } }); } }
/** * 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待 */ @Test public void Test02() { ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3); for (int i = 0; i < 100; i++) { newFixedThreadPool.execute(new Runnable() { public void run() { System.out.println(Thread.currentThread().getName()); } }); } }
/** * 创建一个周期线程池,支持定时及周期性任务执行 队列无限长 */ @Test public void Test03() { ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(3); for (int i = 0; i < 100; i++) { newScheduledThreadPool.schedule(new Runnable() { public void run() { System.out.println(Thread.currentThread().getName()); } }, 3, TimeUnit.SECONDS); } }
/** * 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行 */ @Test public void Test04() { ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor(); for (int i = 0; i < 100; i++) { newSingleThreadExecutor.execute(new Runnable() { public void run() { System.out.println(Thread.currentThread().getName()); } }); } }
注:不推荐使用Executors创建线程池,因为看源码队列是无限长也就是无界队列消耗资源,高并发下很快会崩。
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
4、自定义线程
我们使用ThreadPoolExecutor来自定义多线程
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
原文:https://www.cnblogs.com/swallower/p/12682615.html