Java常见线程池示例

2018-01-18  本文已影响111人  老羊_肖恩

  Java通过Executors提供了四种常见的线程池框架,分别为:
newFixedThreadPool:创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
newSingleThreadExecutor:创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
newCachedThreadPool:创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。
newScheduledThreadPool:创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
接下来简单介绍一下这四种常用线程池的用法。

newFixedThreadPool

  创建方法:

public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newFixedThreadPool(int nThreads,ThreadFactory threadFactory)

    newFixedThreadPool创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。在任意点,在大多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地 关闭之前,池中的线程将一直存在。
示例代码:

/**
     * 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
     * 定长线程池的大小最好根据系统资源进行设置。
     */
    public static void newFixedThreadPoolDemos(){
        ExecutorService pool = Executors.newFixedThreadPool(3);
        
        for(int i = 0; i < 10; i++){
            final int index = i;
            pool.execute(()->{
                System.out.println("execute" + index);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    System.out.println("Exception during sleep->" + e.getMessage());
                }
            });
        }
        System.out.println("isShutdown: " + pool.isShutdown() + "   isTerminated: " + pool.isTerminated());
        pool.shutdown();
//      pool.shutdownNow();
        System.out.println("isShutdown: " + pool.isShutdown() + "   isTerminated: " + pool.isTerminated());

        
        try {
            Thread.sleep(10000);
            System.out.println("isShutdown: " + pool.isShutdown() + "   isTerminated: " + pool.isTerminated());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

newCachedThreadPool

  创建方法:

public static ExecutorService newCachedThreadPool();
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);

  创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。
示例代码:

/**
     * newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,
     * 可灵活回收空闲线程,若无可回收,则新建线程。线程池为无限大,当执行第二个
     * 任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
     * 示例代码如下:
     */
    public static void newCachedThreadPoolDemos(){

        ExecutorService pool = Executors.newCachedThreadPool();
        for(int i = 0; i < 10; i++){
            final int index = i;
//          try{
//              Thread.sleep(index * 100);
//          }catch (InterruptedException e) {
//              e.printStackTrace();
//          }
            pool.submit(()->{
                System.out.println("submit->" + index);
                return null;
            });
//          pool.execute(()->{
//              System.out.println("execute->" + index);
//          });
        }
        System.out.println("------------------------------");
        pool.shutdown();
        pool.shutdownNow();
        System.out.println("isShutdown: " + pool.isShutdown());
        
        try {
            pool.execute(()->{
                System.out.println("after shutdown~~");
            });
        } catch (Exception e) {
            System.out.println("Exception after shutdown~~~~" + e.getMessage());
        }
        
    }

newScheduledThreadPool()

  创建方法:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize);
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize,ThreadFactory threadFactory);

  创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。corePoolSize - 池中所保存的线程数,即使线程是空闲的也包括在内。
示例代码:

/**
     * 创建一个定长线程池,支持定时及周期性任务执行。
     */
    public static void newScheduledThreadPoolDemos(){
        System.out.println("start ... " + new Date());
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
        //表示延迟3秒执行
//      pool.schedule(()->{
//          System.out.println("delay 3 seconds...");
//      }, 3, TimeUnit.SECONDS);
        
        //延迟10秒后每3秒执行一次
        pool.scheduleWithFixedDelay(()->{
            System.out.println("delay 2 seconds..." + new Date());
        }, 10, 3, TimeUnit.SECONDS);
    }
}

newSingleThreadExecutor()

  创建方法:

public static ExecutorService newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory);

  创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,那么如果需要,一个新线程将代替它执行后续的任务)。可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。与其他等效的 newFixedThreadPool(1) 不同,可保证无需重新配置此方法所返回的执行程序即可使用其他的线程。
示例代码:

/**
     * 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,
     * 保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
     * (可通过实现ThreadFactory来实现,newSingleThreadExecutor(ThreadFactory threadFactory))。
     */
    public static void newSingleThreadExecutorDemos(){
        ExecutorService pool = Executors.newSingleThreadExecutor();
        for(int i = 0; i < 10; i++){
            final int index = i;
            pool.execute(()->{
                System.out.println("execute -> " + index);
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    System.out.println("Exception during sleep: " + e.getMessage());
                }
            });
        }
        pool.shutdown();
    }
上一篇 下一篇

猜你喜欢

热点阅读