如果程序中创建了大量的生命周期很短的线程,则该使用线程池。一个线程池包含许多组合南北运行的空闲线程。将Runnable对象交给线程池,就会有一个线程调用run方法。当run方法退出时,线程不会死亡,而是在池中准备为下一个请求提供服务。
- 减少并发线程的数目。创建大量线程会大大降低性能甚至使虚拟机奔溃。
14.9.1线程池
可用下面的方法之一将一个Runnale对象或Callable对象提交给Executorservice:
- Future<?> subit(unnable task)
- FuturecT sbit(unnable task, T result)
- Future subit(CallablecT> task)
该池会在方便的时候尽早执行提交的任务。用来查询该任务的状态。
第一个submit方法返同一个奇怪样子的Future<?>。可以使用这样个对象来调用isDone cancel 或isCacellede。但是,get 方法在完成的时候只是简单地返回null。
第二个版本的Submit也提交个Runnable,并且Future的get方法在完成的时候返回指定的result对象。
第三个版本的Submit提交个allable,并且返回的Future对象将在计算结果准备好的时候得到它。
当用完一个线程池的时候,调用shutdown。该方法启动该池的关闭序列。被关闭的执行器不再接受新的任务。当所有任务都完成以后,线程池中的线程死亡。另种 方法是调用shutdownNow。该池取消尚未开始的所有任务并试图中断正在运行的线程,
下面总结了在使用连接池时应该做的事:
- 1 )调用Exccutors类中静态的方法newCachedThreadPool或newFixedThrcadPool
- 2 )调用submit提交Runnable或Callable对象。
- 3)如果想要取消一个任务,或如果提交Callable对象,那就要保存好返回的Future对象。
- 4)当不再提交任何任务时,调用shutdown。
14.9.2 预定执行
ScheduledExecutorService 接口具有为预定执行或重复执行任务而设计的方法。它是一种允许使用线程池机制的java.util.Timer的泛化。Executors类的newScheduledThreadPool和newSingleThreadScheduledExecutor方法将返回实现了ScheduledExecutorService接口的对象。
ScheduledExecutorService
- scheduleAtFixedRate(Runnable task, long initialDelay, long period, TimeUnit unit)
预定在初始的延迟结束后,周期性地运行给定的任务,周期长度是period。Runnable runnable = ()->{ System.out.println(System.currentTimeMillis()/1000); System.out.println(num); num++; }; System.out.println("begin\t" + System.currentTimeMillis()/1000); ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); //延迟4秒,每隔5秒执行 executorService.scheduleAtFixedRate(runnable,4,5, TimeUnit.SECONDS);
ScheduledExecutorService
- scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit);
预定在初始的延迟结束后周期性地运行给定的任务,在一次调用完成和下一次调用开始前有长度为delaaay的延迟。Runnable runnable = ()->{ System.out.println(System.currentTimeMillis()/1000); System.out.println(num); num++; }; System.out.println("begin\t" + System.currentTimeMillis()/1000); ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.scheduleWithFixedDelay(runnable,4,5,TimeUnit.SECONDS);
14.9.3控制任务组
invokeAny方法提交所有对象到一个Callable对象的集合中,并返回某个已经完成了的任务的结果。
- 解码RSA密码;
invokeAll返回所有任务的执行结果;提交所有对象到一个Callable对象的集合中,并返回一个Future对象的列表。
ExecutorCompletionService