4种JDK自带线程池介绍

一、4种基本线程池

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

1.newCachedThreadPool可缓存线程池

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
  1. 这种线程池内部没有核心线程,线程的数量是有没限制的。
  2. 在创建任务时,若有空闲的线程时则复用空闲的线程,若没有则新建线程。
  3. 没有工作的线程(闲置状态)在超过了60S还不做事,就会销毁。

2.FixedThreadPool 定长线程池

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
  • 该线程池的最大线程数等于核心线程数,所以在默认情况下,该线程池的线程不会因为闲置状态超时而被销毁。
  • 如果当前线程数小于核心线程数,并且也有闲置线程的时候提交了任务,这时也不会去复用之前的闲置线程,会创建新的线程去执行任务。如果当前执行任务数大于了核心线程数,大于的部分就会进入队列等待。等着有闲置的线程来执行这个任务。

3.SingleThreadPool

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}
  1. 有且仅有一个工作线程执行任务
  2. 所有任务按照指定顺序执行,即遵循队列的入队出队规则

4.ScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

//ScheduledThreadPoolExecutor():
public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE,
          DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
          new DelayedWorkQueue());
}

DEFAULT_KEEPALIVE_MILLIS就是默认10L,这里就是10秒。这个线程池有点像是吧CachedThreadPool和FixedThreadPool 结合了一下。

  1. 不仅设置了核心线程数,最大线程数也是Integer.MAX_VALUE。
  2. 这个线程池是上述4个中为唯一个有延迟执行和周期执行任务的线程池。

二、例子

package xu.threadPool;

import java.util.concurrent.*;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class poolMain {
    public static void main(String[] arg0) throws Exception {
        int corePoolSize = 10;  //核心线程数
        int maximumPoolSize = 50; //最大线程数
        long keepAliveTime = 1000; //非核心线程的休眠时间   TimeUnit.MILLISECONDS  毫秒
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(1000); //大小1000的阻塞队列
        ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 默认线程工厂
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); //默认拒绝规则,直接异常
        ThreadPoolExecutor pool = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit.MILLISECONDS,workQueue,threadFactory,handler);
        for(int i = 0 ; i<10;i++){
            pool.execute(new threadCMD("threa" + i));
        }
        //获取值的线程池
        Future future = pool.submit(new callableCMD("callable"));
        System.out.println("开始尝试获取返回值:");
        System.out.println("获取到内容:" + future.get());//get是阻塞的。

        pool.shutdown();//关闭线程池,队列中会继续执行。
        System.out.println("shutDown完成");

        ScheduledExecutorService schedulePool = Executors.newScheduledThreadPool(1);
        schedulePool.schedule(new threadCMD("定时任务schedule"),1000,TimeUnit.MILLISECONDS);
        schedulePool.scheduleWithFixedDelay(new threadCMD("循环任务schedule"),0,1000,TimeUnit.MILLISECONDS);//表示以固定延时执行任务,延时是相对当前任务结束为起点计算开始时间。
        schedulePool.scheduleAtFixedRate(new threadCMD("循环任务schedule2"),0,1000,TimeUnit.MILLISECONDS);//表示以固定频率执行的任务,如果当前任务耗时较多,超过定时周期period,则当前任务结束后会立即执行。
    }
}
package xu.threadPool;

import java.util.Date;

public class threadCMD implements Runnable {
    String name;
    threadCMD(String name){
        this.name = name;
    }


    public void run() {
        try {
            System.out.println("线程" + name + ":运行时间" + new Date());
            Thread.sleep(2000);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
package xu.threadPool;

import java.util.concurrent.Callable;

public class callableCMD implements Callable<String> {
    String name;
    callableCMD(String name){
        this.name = name;
    }

    public String call() throws Exception {
        System.out.println("线程" + name +":运行,休眠1000ms");
        Thread.sleep(1000);
        System.out.println("线程" + name +":休眠结束");
        return name;
    }
}

 

posted @ 2021-04-19 17:11  xujf  Views(429)  Comments(0Edit  收藏  举报