程序员

java_线程池

2018-02-22  本文已影响65人  飞翔的鲲

Executors


四种线程池

  1. newFixedThreadPool(int var0)
    固定线程数, 使用了LinkedBlockingQueue队列。
   public static ExecutorService newFixedThreadPool(int var0) {
        return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
    }
  1. newCachedThreadPool()
 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());
    }
  1. newSingleThreadExecutor()
    单个线程任务,队列为LinkedBlockingQueue
    public static ExecutorService newSingleThreadExecutor() {
        return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
    }
  1. newScheduledThreadPool(int var0)
    定时任务,队列为DelayedWorkQueue
    public static ScheduledExecutorService newScheduledThreadPool(int var0) {
        return new ScheduledThreadPoolExecutor(var0);
    }

    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
              new DelayedWorkQueue());
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              //线程空闲时的存活时间,即当线程没有任务执行时,继续存活的时间。默认情况下,该参数只在线程数大于corePoolSize时才有用
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

阻塞队列


参考
https://www.jianshu.com/p/4028efdbfc35

阻塞队列是一种队列,一种可以在多线程环境下使用,并且支持阻塞等待的队列。也就是说,阻塞队列和一般的队列的区别就在于:
1.多线程环境支持,多个线程可以安全的访问队列
2.支持生产和消费等待,多个线程之间互相配合,当队列为空的时候,消费线程会阻塞等待队列不为空;当队列满了的时候,生产线 程就会阻塞直到队列不满。

非阻塞队列


取的时候不会阻塞等待

add():底层调用offer();

offer():Queue接口继承下来的方法,实现队列的入队操作,不会阻碍线程的执行,插入成功返回true;
poll():移动头结点指针,返回头结点元素,并将头结点元素出队;队列为空,则返回null;

peek():移动头结点指针,返回头结点元素,并不会将头结点元素出队;队列为空,则返回null;

底层实现ThreadPoolExecutor


Java线程池ThreadPoolExecutor使用和分析(一)
http://www.cnblogs.com/trust-freedom/p/6594270.html
Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理
https://www.cnblogs.com/trust-freedom/p/6681948.html

image.png image.png

说明:

在图1中,线程池中有N个任务。"任务1", "任务2", "任务3"这3个任务在执行,而"任务3"到"任务N"在阻塞队列中等待。正在执行的任务,在workers集合中,workers集合包含3个Worker,每一个Worker对应一个Thread线程,Thread线程每次处理一个任务。

当workers集合中处理完某一个任务之后,会从阻塞队列中取出一个任务来继续执行,如图2所示。图2表示"任务1"处理完毕之后,线程池将"任务4"从阻塞队列中取出,放到workers中进行处理。

    public ThreadPoolExecutor(int corePoolSize, // 核心线程数
                              int maximumPoolSize, // 最大线程数
                              long keepAliveTime,
                              TimeUnit unit,
                              // 队列
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              // 拒绝执行处理器
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
// 所有工作线程
private final HashSet<Worker> workers = new HashSet<Worker>();
// 存储runnable的队列
 private final BlockingQueue<Runnable> workQueue;

2.addWorker() -- 添加worker线程


image.png

3.runWorker() -- 执行任务
会调用getTask()获取runnable


image.png

4.getTask() -- 获取任务
从阻塞队列拿runnable


image.png
上一篇下一篇

猜你喜欢

热点阅读