线程池框架Executor创建线程池

以上成员均在java.util.concurrent包中,是JDK并发包的核心类。其中ThreadPoolExecutor表示一个线程池。Executors类则扮演着线程池工厂的角色,通过Executors可以取得一个拥有特定功能的线程池。从UML图中亦可知,ThreadPoolExecutor类实现了Executor接口,因此通过这个接口,任何Runnable的对象都可以被ThreadPoolExecutor线程池调度。 

 newFixedThreadPool()方法:该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。

newSingleThreadExecutor()方法:该方法返回一个只有一个线程的线程池。若多余一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。

newCachedThreadPool()方法:该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。

newSingleThreadScheduledExecutor()方法:该方法返回一个ScheduledExecutorService对象,线程池大小为1。ScheduledExecutorService接口在ExecutorService接口之上扩展了在给定时间执行某任务的功能,如在某个固定的延时之后执行,或者周期性执行某个任务。

newScheduledThreadPool()方法:该方法也返回一个ScheduledExecutorService对象,但该线程池可以指定线程数量。

public class ThreadPoolDemo {
    public static class MyTask implements  Runnable{

        @Override
        public void run() {
            System.out.println(System.currentTimeMillis()+"Thread ID:"+Thread.currentThread().getId());
            try {
                Thread.sleep(1000);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

        public static void main(String[] args) {
            MyTask task = new MyTask();
            ExecutorService es = Executors.newFixedThreadPool(3);
            for (int i = 0; i<10; i++){
                es.submit(task);
            }
        }
    }
}

 

 每一秒执行3个。

换成newCachedThreadPool,会一下子执行完毕。

/**
 * 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. 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. 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.

对应的翻译

创建一个线程池,根据需要创建新线程,但是

*将重用之前构建的线程

*可用。这些池通常会提高性能

执行许多短期的异步任务的程序。

*调用{@code execute}将重用之前构造的

*线程(如果可用)。如果没有可用的线程,则使用新线程

*线程将被创建并添加到池中。线程,

*未使用60秒将终止并删除

*缓存。因此,一个足够长时间保持空闲的池将会

*不消耗任何资源。注意,有类似的池

*属性,但不同的细节(例如,超时参数)

*可以使用{@link ThreadPoolExecutor}构造函数创建。

 newScheduledThreadPool(),它返回一个ScheduledExecutorService对象,可以根据时间需要对线程进行调度。

而scheduleAtFixedRate和scheduleWithFixedDelay,它们的任务都开始于给定的初始延时,不同之处在于后期任务,前者按给定的周期,后者是按给定的 延时。

public class ScheduledExecutorServiceDemo {
    public static void main(String[] args) {
        ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);
        ses.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try{
                    Thread.sleep(1000);
                    System.out.println(System.currentTimeMillis()/1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },0,2, TimeUnit.SECONDS);
    }

}

若改变Thread.sleep(5)的时间大于执行周期时间,那么执行周期时间就会变成大的那个时间,比如sleep(5),而执行周期是2秒。那么运行结果的执行周期也会变成5秒。

上面的核心线程池(比如 newFixedThreadPool(),newCachedThreadPool())的内部都实现ThreadPoolExecutor

其源码:

  public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

corePoolSize:指定了线程池中的线程数量。
maximumPoolSize:指定了线程池中的最大线程数量。
keepAliveTime:当线程池线程数量超过corePoolSize时,多余的空闲线程的存活时间。即,超过corePoolSize的空闲线程,在多长时间内,会被销毁。
unit:keepAliveTime的单位。
workQueue:任务队列,被提交但尚未被执行的任务。
threadFactory:线程工厂,用于创建线程,一般用默认的即可。
handler:拒绝策略。当任务太多来不及处理,如何拒绝任务。

不经一番彻骨寒,哪有梅花扑鼻香?
原文地址:https://www.cnblogs.com/zongyao/p/13831095.html