【线程池概念】
由于系统启动一个新线程的成本是比较高的,因为他涉及与操作系统的交互(这也就是为什么可以有百万个Goroutines,却只有几千个java线程)。在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要大量生存期很短暂的线程时,更应该考虑使用线程池。
与数据库连接池类似的是,线程池在系统启动时即创建大量空闲的线程,程序将一个Runnable对象或Callable对象传给线程池,线程池就会启动一个空闲的线程来执行它们的run()或call()方法,当run()或call()方法执行结束之后,该线程并不会死亡,而是再次放回线程池中成为空闲状态,等待下一个Runnable对象的run()或call()方法。
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPool { public static void main(String[] args) throws Exception { //创建一个具有固定线程数的线程池 ExecutorService pool = Executors.newFixedThreadPool(10); //使用Lambda表达式创建Runnable对象 Runnable target = () -> { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "的i值为:" + i); } }; //向线程池中提交两个线程 pool.submit(target); pool.submit(target); //关闭线程池 pool.shutdown(); } }
上面的程序中创建Runnable实现类与最开始创建线程池并没有太大差别,创建了Runnable实现类之后程序没有直接创建线程、启动线程来执行该Runnable任务,而是通过线程池来执行该任务,打印结果如下:
此外,在java8中,还改进了很多对线程池的方法,这些增强的方法有些和设计模式有联系,作以相关参考。