首先,线程池。 让我们直接进入java.util.concurrent.ExecutorService ,它为我们提供了线程池的基本接口。 所有线程池都允许提交CallableRunnable实例以供将来执行。 它们还提供各种池管理方法。

泳池管理

池存在各种管理方法。 您可以使用shutdown()池,该池将拒绝将来的所有提交,但将完全处理进程内执行,甚至还包括尚未开始但在关闭启动之前提交的进程。 您还可以更积极地执行shutdownNow()。 这也将阻止将来提交任何内容,但是它具有一些不同的显着行为。 它不会开始执行已提交但尚未开始的任务。 它们将在返回的列表中。 它还将尝试停止或更准确地说是当前正在执行任务的Thread.interrupt() 。 这是最大的努力,不能保证成功完成这些任务。

线程工厂

稍后,我们将进入java.util.concurrent.Executors构建器类,该类可以创建各种线程池配置,但首先让我们集中讨论使用ThreadFactory。 您将需要利用Executor中ThreadFactory支持,并养成提供自己的习惯。 默认的ThreadFactory将为您提供一个递增编号的池命名方案,这在日志或其他监视中并不是很有用。 对于创建的第一个池,您将获得名为pool-1-thread-1pool-1-thread-2的线程 ,第二个以pool-2-thread-1开头的线程 ,等等。通过提供自己的ThreadFactory ,您可以具有名为ReportProcessingThread1HttpThread1的线程。 这是一个简单的例子:

private AtomicLong counter = new AtomicLong();
private String name;
public Thread newThread(Runnable r) {
	Thread t = new Thread(r);
	t.setName(name + counter.incrementAndGet());
	return t;
}

仅当创建新线程时才调用ThreadFactory 。 鉴于JDK线程池将尽可能重用线程,因此不能使用此类来管理执行的开始。

执行器生成器方法

现在回到Executors实用程序构建器方法。 他们是:

  • newCachedThreadPool()将为您提供一个线程池,该线程池将在可能的情况下重用线程,并根据需要创建新线程,而没有配置的限制。
  • newFixedThreadPool(int nThreads)将为您提供一个线程池,该线程池将仅使用指定数量的线程,但将接受与提交的任务一样多的任务,以便按提交顺序运行它们。
  • newScheduledThreadPool(int corePoolSize)专门用于按延迟执行的周期性计划来调度执行延迟的线程。 返回的线程池实现ScheduledExecutorService ,该服务公开了其他调度方法schedule(Runnable命令,长延迟,TimeUnit单位)scheduleAtFixedRate(Runnable命令,长initialDelay,长周期,TimeUnit单位)scheduleWithFixedDelay(Runnable命令,长initialDelay,长延迟, TimeUnit单位)
  • newSingleThreadExecutor()newSingleThreadScheduledExecutor() 。 这些对可以提交的任务数量没有限制,仅确保一次执行单个线程/任务。

最后,有一些帮助方法可用于从Runnable创建Callable实例。 这使我们进入了新创建的结构中,该结构允许线程引发Exception和返回值,这是我们以前不得不非常痛苦地解决的问题。 在下一篇文章中,我们将考虑这些以及它们如何与这些线程池一起使用。

参考: Java并发第3部分–来自我们的JCG合作伙伴的Carfey Software博客上的 线程池



相关文章 :



  • Java并发教程–信号量
  • Java并发教程–重入锁
  • Java并发教程–可调用,将来
  • Java并发教程–阻塞队列
  • Java并发教程– CountDownLatch
  • Exchanger和无GC的Java
  • Java Fork / Join进行并行编程
  • 使用迭代器时如何避免ConcurrentModificationException
  • 改善Java应用程序性能的快速技巧



翻译自: https://www.javacodegeeks.com/2011/09/java-concurrency-tutorial-thread-pools.html