1,线程池的概念
线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。
最初是程序员自己开发线程池:用ArrayList<Thread>集合存储多个线程,只要ArrayList在,线程就不会消失!程序一开始,创建多个线程对象,存储在集合中(add(new Thread())),每次需要线程的时候从集合中取线程(t = remove(0)),线程用完了之后,要放回集合中(add(t))。
从JDK5之后,内置了线程池技术,不需要自己写了!
2,使用线程池的方式
通常,线程池通过线程池工厂创建,再调用线程池中的方法获取线程,再通过线程去执行任务方法。
2.1 Executors类(线程池工厂类)
主要用来创建线程池,其中全是静态方法,无构造方法
public static ExecutorService newFixedThreadPool(int nThreads) 创建一个可规定固定线程数的线程池(以共享的无界队列方式来运行这些线程),返回ExecutorService接口的实现类ThreadPoolExecutor(线程池对象)
2.2 ExecutorService接口(线程池)
public Future submit(Runnable task) 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future接口的实现类。
public Future submit(Callable<T> task) 提交一个Callable的任务用于执行,返回一个表示任务的未决结果的 Future接口的实现类。
(Future接口:用来记录线程任务执行完毕后产生的结果。)
shutdown() 销毁线程池
接口的实现类ThreadPoolExecutor对象,调用submit(Runnable t)方法,提交线程,执行任务!
2.3 Callable<V>接口(相当于Runnable接口)
实现线程程序的第三种定义方式!该接口就是Runnable接口的升级版,其中有public V call()方法,相当于Runnable接口的run()方法,只不过call()方法增加了:
1. 可以抛异常
2. 可以有返回值V(在submit()中,其返回值由Future接口的实现类接收,futurer.get()获取)
2.3 代码演示: