关于后端:Executors中提供的几种常用的线程池

5次阅读

共计 1945 个字符,预计需要花费 5 分钟才能阅读完成。

1. newFixedThreadPool 固定数目线程的线程池

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

线程池特点:

外围线程数和最大线程数大小一样

没有所谓的非闲暇工夫,即 keepAliveTime 为 0

阻塞队列为无界队列 LinkedBlockingQueue

工作机制:

  • 提交工作
  • 如果线程数少于外围线程,创立外围线程执行工作
  • 如果线程数等于外围线程,把工作增加到 LinkedBlockingQueue 阻塞队列
  • 如果线程执行完工作,去阻塞队列取工作,继续执行。

应用无界队列的线程池会导致内存飙升吗?

会的,newFixedThreadPool 应用了无界的阻塞队列 LinkedBlockingQueue,如果线程获取一个工作后,工作的执行工夫比拟长,会导致队列的工作越积越多,导致机器内存应用不停飙升,最终导致 OOM。

应用场景

FixedThreadPool 实用于解决 CPU 密集型的工作,确保 CPU 在长期被工作线程应用的状况下,尽可能的少的调配线程,即实用执行长期的工作。

newCachedThreadPool 可缓存线程的线程池

public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>(),
                                  threadFactory);
}

线程池特点:

外围线程数为 0

最大线程数为 Integer.MAX_VALUE

阻塞队列是 SynchronousQueue

非核心线程闲暇存活工夫为 60 秒

当提交工作的速度大于解决工作的速度时,每次提交一个工作,就必然会创立一个线程。极其状况下会创立过多的线程,耗尽 CPU 和内存资源。因为闲暇 60 秒的线程会被终止,长时间放弃闲暇的 CachedThreadPool 不会占用任何资源。

工作机制

  • 提交工作
  • 因为没有外围线程,所以工作间接加到 SynchronousQueue 队列。
  • 判断是否有闲暇线程,如果有,就去取出工作执行。
  • 如果没有闲暇线程,就新建一个线程执行。
  • 执行完工作的线程,还能够存活 60 秒,如果在这期间,接到工作,能够持续活下去;否则,被销毁。

应用场景

用于并发执行大量短期的小工作。

newSingleThreadExecutor 单线程的线程池

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

线程池特点

外围线程数为 1

最大线程数也为 1

阻塞队列是 LinkedBlockingQueue

keepAliveTime 为 0

工作机制

  • 提交工作
  • 线程池是否有一条线程在,如果没有,新建线程执行工作
  • 如果有,将工作加到阻塞队列
  • 以后的惟一线程,从队列取工作,执行完一个,再持续取,一个人(一条线程)披星戴月地干活。

应用场景

实用于串行执行工作的场景,一个工作一个工作地执行。

newScheduledThreadPool 定时及周期执行的线程池

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

线程池特点

最大线程数为 Integer.MAX_VALUE

阻塞队列是 DelayedWorkQueue

keepAliveTime 为 0

scheduleAtFixedRate():按某种速率周期执行

scheduleWithFixedDelay():在某个提早后执行

工作机制

  • 增加一个工作
  • 线程池中的线程从 DelayQueue 中取工作
  • 线程从 DelayQueue 中获取 time 大于等于以后工夫的 task
  • 执行完后批改这个 task 的 time 为下次被执行的工夫
  • 这个 task 放回 DelayQueue 队列中

应用场景

周期性执行工作的场景,须要限度线程数量的场景

正文完
 0