如同数据库链接同样,线程的建立、切换和销毁一样会耗费大量的系统资源。为了复用建立好的线程,减小频繁建立线程的次数,提升线程利用率能够引用线程池技术。使用线程池的优点有以下几点:
一、保持必定数量的线程,减小了线程频繁建立和销毁资源消耗。
二、使用线程的时候直接由线程池中取出线程,省去了建立线程的时间,侧面提升了系统的响应时间。
三、须要使用线程的时候直接从线程池中取出,避免了人为的不合理建立线程,减小了潜在的风险。
Doug Lea在实现JUC中提供了原生的线程池,并提供了各类线程管理策略来适应于不一样的使用场景。使用的时候可经过Executors获取各类线程池实例。html
这里提供了六对12个方法来建立ExecutorService,其中每种类型的ExecutorService能够适用于不一样的应用场景,对线程的管理策略也各不相同。下面就看一下各个方法的注释:java
/** * Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. * 建立一个线程池,须要的时候会建立新的线程,若是有可用的线程则会复用之前已经建立好的线程。 * These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. * 这些线程池一般状况下能够提高哪些短时间异步任务的性能 * Calls to {@code execute} will reuse previously constructed threads if available. * 若是以建立的线程状态可用的话,调用execute能够复用他们 * If no existing thread is available, a new thread will be created and added to the pool. * 若是不存在可用状态的线程,那么将会建立一个新线程同时会把该线程添加到线程池中 * Threads that have not been used for sixty seconds are terminated and removed from the cache. *那些超过60s没用的线程将会被销毁同时从缓存中移除 * Thus, a pool that remains idle for long enough will not consume any resources. *所以长时间空闲的线程池不会消耗任何资源 * Note that pools with similar properties but different details (for example, timeout parameters) may be created using {@link ThreadPoolExecutor} constructors. *可使用ThreadPoolExecutor建立性质类似但实现细节不一样的线程池 * @return the newly created thread pool */ public static ExecutorService newCachedThreadPool(); //可使用自定义的ThreadFactory 类建立线程,其它和无参方法一致 public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);
/** * Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. *建立一个可重用、固定数量线程的线程池 * At any point, at most {@code nThreads} threads will be active processing tasks. *任什么时候间最多只有 nThreads 个线程被激活来执行任务 * If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. * 当无可用空闲线程的时候,若是有新任务被提交,这些新任务将会一直等待直至有可用线程来执行。 * If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. *若是任何线程正常关闭以前在执行过程当中因失败而提早终止,那么若是有未被执行的后续任务,则会建立新的线程来继续执行。 * The threads in the pool will exist until it is explicitly {@link ExecutorService#shutdown shutdown}. * 线程池中的全部线程在明确掉用shutdown以后将会退出 * * @param nThreads the number of threads in the pool * @return the newly created thread pool * @throws IllegalArgumentException if {@code nThreads <= 0} */ public static ExecutorService newFixedThreadPool(int nThreads); //可自定义ThreadFactory public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);
/** * Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically. * 建立一个线程池,该线程在延迟指定时间以后能够周期性的执行线程体 * @param corePoolSize the number of threads to keep in the pool, * even if they are idle * @return a newly created scheduled thread pool 注意返回值类型是ScheduledExecutorService,不要使用ExecutorService来接收,不然找不到schedule执行方法 * @throws IllegalArgumentException if {@code corePoolSize < 0} */ public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize); //可自定义ThreadFactory public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);
/** * Creates an Executor that uses a single worker thread operating off an unbounded queue. *建立一个Executor,使用一个线程来工做,该线程存储在LinkedBlockingQueue中 * (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) *注,若是任何线程正常关闭以前在执行过程当中因失败而提早终止,那么若是有未被执行的后续任务,则会建立新的线程来继续执行。 * Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. * 任务是按顺序执行的,任什么时候间都只有一个线程来执行任务 * Unlike the otherwise equivalent {@code newFixedThreadPool(1)} the returned executor is guaranteed not to be reconfigurable to use additional threads. * * @return the newly created single-threaded Executor */ public static ExecutorService newSingleThreadExecutor(); //可自定义ThreadFactory public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory);
/** * Creates a single-threaded executor that can schedule commands * to run after a given delay, or to execute periodically. * (Note however that if this single * thread terminates due to a failure during execution prior to * shutdown, a new one will take its place if needed to execute * subsequent tasks.) Tasks are guaranteed to execute * sequentially, and no more than one task will be active at any * given time. Unlike the otherwise equivalent * {@code newScheduledThreadPool(1)} the returned executor is * guaranteed not to be reconfigurable to use additional threads. * @return the newly created scheduled executor */ public static ScheduledExecutorService newSingleThreadScheduledExecutor(); public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory)
使用示例:数据库
package thread.blogs.threadpool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * Created by PerkinsZhu on 2017/8/31 13:59. */ public class PoolTest { public static void main(String[] args) { // testCachedThreadPool(); // testSingleThreadExecutor(); // testFixedThreadPool(); testScheduledThreadPool(); } private static ThreadFactory myFactory = new MyThreadFactory(); private static void testSingleThreadExecutor() { //一个一个的依次执行 doHandle(Executors.newSingleThreadExecutor(myFactory)); } private static void testFixedThreadPool() { //两个两个的一块儿执行 doHandle(Executors.newFixedThreadPool(2,myFactory)); } private static void testCachedThreadPool() { //10个一块儿一次性执行完 doHandle(Executors.newCachedThreadPool(myFactory)); } private static void testScheduledThreadPool() { //定时周期执行 Executors.newScheduledThreadPool(1,myFactory).scheduleAtFixedRate(runnable, 500, 2000, TimeUnit.MILLISECONDS); } private static Runnable runnable = () -> { sleep(1000); System.out.println(Thread.currentThread().getName() + " work!!!"); }; private static void doHandle(ExecutorService executorService) { for (int i = 0; i < 10; i++) { executorService.execute(runnable); } executorService.shutdown(); } private static void sleep(int time) { try { Thread.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } } } class MyThreadFactory implements ThreadFactory {//自定义ThreadFactory private static final AtomicInteger poolNumber = new AtomicInteger(1); private final ThreadGroup group; private final AtomicInteger threadNumber = new AtomicInteger(1); private final String namePrefix; MyThreadFactory() { SecurityManager s = System.getSecurityManager(); group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); namePrefix = "☆☆☆--" + poolNumber.getAndIncrement() + "-****-"; } public Thread newThread(Runnable r) { Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); if (t.isDaemon()) { t.setDaemon(false); } if (t.getPriority() != Thread.NORM_PRIORITY) { t.setPriority(Thread.NORM_PRIORITY); } return t; } }
在使用的时候必须明白各类线程池是否适用于本身的情景,选取合适的线程池进行使用。缓存
=========================================多线程
原文连接:多线程(七)JDK原生线程池转载请注明出处!异步
=========================================async
---endpost