多线程 - 线程池的实现
来源:互联网 发布:淘宝发货地址怎么修改 编辑:程序博客网 时间:2024/06/05 10:02
概述
系统启动一个新线程的成本是比较高的,因为它需要与系统交互,使用线程池可以有效地控制系统中并发线程的数量。尤其是当系统中需要创建大量生命周期很短的线程时,这种效果尤为明显。
线程池会在程序启动时创建一定数量的线程。当程序将一个Runnable对象或Callable对象传给线程池,线程池会启动一个线程来执行它的run()方法或call()方法。当run()方法或call()方法执行结束后,该线程不会立刻死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。
API
从Java 5以后,JDK新增了一个Executors工厂类来创建线程池,该工厂类包含如下几个静态方法:
- newCachedThreadPool():创建一个具有缓冲功能的线程池,系统根据需要创建线程,这些线程将会被缓存在线程池中。
- newFixedThreadPool(int nThreads):创建一个可重用、具有固定线程数的线程池。
- newSingleThreadExecutor():创建一个只有一个线程的线程池。
- newScheduledThreadPool(int corePoolSize):创建具有指定线程数的线程池,它可以在指定延迟后执行任务。corePoolSize指线程池中所保存的线程数,即使线程是空闲的也被保存在线程池内。
- newSingleThreadScheduledExecutor():创建只有一个线程的线程池,它可以在指定延迟后执行任务。
前3个方法返回一个ExecutorService对象,它代表线程池,可以执行Runnable或Callable任务。后2个方法返回一个ScheduledExecutorService对象,它是ExecutorService的子类,在指定延迟后执行线程任务。ExecutorService提供了3个方法来执行线程任务:
- Future<?> submit(Runnable task):将一个Runnable任务提交给线程池,线程池将在有空闲线程是执行Runnable任务。Future对象代表Runnable任务的返回值——run()方法没有返回值,将返回null。
- <T> Future<T> submit(Runnable task, T result):将一个Runnable任务提交给线程池,线程池将在有空闲线程是执行Runnable任务。其中result表示返回值,线程执行结束后返回result。
- <T> Future<T> submit(Callable<T> task):将一个Callable任务提交给线程池,线程池将在有空闲线程是执行Callable任务。Future对象代表Callable任务的返回值。
当执行完线程任务后,应该关闭线程池。调用shutdown()方法后,线程池将不再接收新的线程任务,并将所有正在执行的线程任务执行完毕后关闭线程池。shutdownNow()方法会停止所有正在执行的线程任务并关闭线程池。
代码示例
使用线程池来执行线程任务的步骤如下:
(1)调用Executors类的静态工厂方法创建一个ExecutorService对象,该对象代表一个线程池;
(2)创建Runnable实现类或Callable实现类的实例,作为线程任务;
(3)调用ExecutorService对象的submit()方法来提交线程任务;
(4)线程任务执行完毕后,关闭线程池。
package Demo;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;class MyTask implements Runnable { @Override public void run() {for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + "的i值为" + i);} }}public class ThreadPoolDemo { public static void main(String[] args) {// 创建线程池,容量为4ExecutorService threadPool = Executors.newFixedThreadPool(4);// 提交三个线程任务threadPool.submit(new MyTask());threadPool.submit(new MyTask());threadPool.submit(new MyTask());// 关闭线程池threadPool.shutdown(); }}
测试结果:
pool-1-thread-1的i值为0pool-1-thread-2的i值为0pool-1-thread-2的i值为1pool-1-thread-2的i值为2pool-1-thread-3的i值为0pool-1-thread-2的i值为3pool-1-thread-1的i值为1pool-1-thread-2的i值为4pool-1-thread-2的i值为5pool-1-thread-2的i值为6pool-1-thread-3的i值为1pool-1-thread-2的i值为7pool-1-thread-2的i值为8pool-1-thread-2的i值为9pool-1-thread-2的i值为10pool-1-thread-2的i值为11pool-1-thread-2的i值为12pool-1-thread-2的i值为13......
0 0
- 多线程 - 线程池的实现
- java多线程、线程池的实现
- concurrent实现多线程的线程池开发
- 多线程之线程池的简单实现
- 多线程中线程池的简单实现
- 多线程 线程队列的实现
- java多线程-线程的实现
- 线程池 Callable实现多线程
- ExecutorService来进行线程池的方式实现多线程
- Java多线程----Java 线程池的原理与实现
- java多线程总结五:线程池的原理及实现
- java多线程总结五:线程池的原理及实现
- java多线程总结五:线程池的原理及实现
- java多线程总结五:线程池的原理及实现
- java多线程总结之:线程池的原理及实现
- Java多线程----Java 线程池的原理与实现
- java多线程 :线程池的原理及实现
- linux c++线程池的实现(多线程服务器)
- Astar Round2B 1005 区间交 区间覆盖 线段树
- 插件入门
- Geek-Band--第十二周分享
- 线程同步:临界区的使用
- 百度之星 初赛2 瞬间转移 HDU 5698 (组合数+逆元)
- 多线程 - 线程池的实现
- java笔记之面向对象,构造,继承
- poj1182 食物链(经典关系并查集)
- 顺序表应用3:元素位置互换之移位算法
- 7-CSS三种样式
- [3]R语言在数据处理上的禀赋——par参数详解(一)
- 队列
- <Android 基础(一)> Service
- JSP-EL表达式