如果想手动创建自己的线程池,那么我们通常使用的是Executors类。下面我们将详细大致讲解:
Executors.newCachedThreadPool()
创建一个线程池,根据需要创建新线程,但在可用线程时将重用以前构建的线程。这些池通常会提高执行许多短期异步任务的程序的性能。
调用执行将重用先前构建的线程,如果可用的话。如果没有现有线程可用,将创建一个新线程并将其添加到池中。未使用六十秒的线程被终
止并从缓存中移除。因此,空闲时间足够长的池不会消耗任何资源。性质相似但不同的细节注意池(例如,超时参数)可以使用构造函数创
建的线程池。
Executors.newSingleThreadExecutor()
创建一个执行器,它使用一个单独的工作线程在无界队列中运行。(但是请注意,如果这个单线程在关闭前执行失败,那么在执行后续任务时需要
一个新的线程。)保证任务按顺序执行,并且在任何给定的时间内都不会有一个任务处于活动状态。不像其他等效创建固定数目线程的线程池(1)
返回的执行是保证不可使用额外的线程。
Executors.newFixedThreadPool(1)
创建一个线程池,使用固定数量的线程操作了共享无界队列。在任何时候,在大多数Nthreads线程将积极处理任务。如果在所有线程处于活动状态
时提交其他任务,则它们将在队列中等待,直到线程可用为止。如果任何线程在关闭前在执行过程中失败,如果需要执行后续任务,则新线程将取代
它。池中的线程将一直存在,直到它显式关闭为止。
Executors.newScheduledThreadPool(0)
创建线程池,可以在给定延迟后调度命令运行,或定期执行命令。
Executors.newWorkStealingPool()
使用所有可用的处理器作为目标并行级别创建一个工作窃取线程池。
submit()方法
提交执行一个Runnable任务并返回一个表示该任务的未来。未来的get方法将在成功完成后返回给定的结果。
invokeAll()方法执行给定的任务,返回一个持有状态的期货列表,并在全部完成时返回结果。对于返回的列表中的每个元素future.isdone是真实的。
注意,完成的任务可以正常终止,也可以抛出异常。如果在进行此操作时对给定集合进行修改,则此方法的结果是不确定的。
invokeAny方法
执行给定的任务,返回已成功完成的任务的结果(即不抛出异常),如果有的话。在正常或异常返回时,未完成的任务被取消。
如果在进行此操作时对给定集合进行修改,则此方法的结果是不确定的。
在正常使用时,我们会发现,当我们submit一个线程后,当前进程是没有退出的。就是说,执行器一致在监听是否有新的任务需要执行,当我们不需要线程池或关闭程序时,需要手动调用shutdown()方法,释放资源。
聪明的你可能发现,关闭线程池还有一个方法shutdownNow(),它和shutdown()稍有不同。当执行shutdownNow()方法时,它会关闭当前正在执行的所有程序,而shutdown()方法执行后,当前线程仍然继续执行,直至执行完毕,但是不再接收新的线程任务。