Java线程池是JDK1.5引入的,可以复用已创建的线程,减少创建和销毁线程所带来的开销。线程池可以有效地控制并发线程的数量,提高系统性能。以下是Java线程池的使用方法和技巧:
- 使用方式:
创建线程池:
ExecutorService executor = Executors.newFixedThreadPool(int nThreads);
其中,nThreads
表示线程池中的线程数目。
提交任务:
executor.execute(Runnable task);
其中,Runnable task
表示要执行的任务。
关闭线程池:
executor.shutdown();
- 关闭线程池:
shutdown()
方法不会立即关闭线程池,而是不再接受新的任务,等待已提交的任务执行完毕后再关闭线程池。
shutdownNow()
方法会立即关闭线程池,并尝试停止正在执行的任务。
- 线程池拒绝策略:
当线程池无法接受新任务时,会采取默认的拒绝策略,即抛出RejectedExecutionException
异常。可以通过重写RejectedExecutionHandler
接口来自定义拒绝策略。
- 线程池线程数量设置:
线程池中的线程数量可以通过构造方法参数进行设置。如果设置为0,则表示不创建线程池,而是使用系统默认的线程池。如果设置为-1,则表示使用CPU核心数作为线程池中的线程数量。
- 线程池任务队列:
线程池中的任务队列用于存储待执行的任务。可以通过构造方法参数指定任务队列的类型和容量。如果未指定,则使用无界任务队列。
- 线程池任务执行顺序:
线程池中的任务执行顺序是不确定的,因为线程池中的线程是并发执行的。如果需要控制任务执行顺序,可以考虑使用有序的任务队列或者使用PriorityBlockingQueue
作为任务队列。
- 线程池监控:
可以通过ThreadPoolExecutor
类提供的getActiveCount()
、getCompletedTaskCount()
、getTaskCount()
等方法来监控线程池的状态。还可以通过Future
对象来获取任务执行结果。
- 线程池与Callable接口:
ExecutorService
接口不支持Callable
接口,如果需要使用Callable
接口,可以使用Executors.callable(Callable task)
方法将Callable
任务转换为Runnable
任务,然后提交给线程池执行。
- 线程池与ForkJoinPool:
ForkJoinPool
是Java 7引入的一种特殊的线程池,用于实现分治算法。它采用工作窃取算法来平衡任务负载,提高任务执行效率。ForkJoinPool
中的任务必须是RecursiveAction
或RecursiveTask
的子类。