【线程池概念】

  由于系统启动一个新线程的成本是比较高的,因为他涉及与操作系统的交互(这也就是为什么可以有百万个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中,还改进了很多对线程池的方法,这些增强的方法有些和设计模式有联系,作以相关参考。