Java线程(二)线程池

来源:互联网 发布:苹果cms有自带采集插件 编辑:程序博客网 时间:2024/05/16 19:42
系统启动一个新线程成本很高,使用线程池能很好的提高性能。尤其当需要创建大量的生存周期很短的线程时,更应该考虑线程池。
线程池在系统启动时会创建大量空闲的线程,将一个Runnable对象或者Callable对象传给线程池,线程池就会启动一个线程来执行run()或者call()方法,执行结束后线程不会死亡,再次返回线程池成为空闲状态,等待执行下一个run()或者call()方法。
创建线程池执行线程的方法:
1.调用Executors类的静态工场方法创建ExecutorService对象,该对象代表一个线程
2.创建Runnable实现类或Callable实现类的实例,作为线程执行任务
3.调用ExecutorService对象的submit()方法提交实例
4.不想提交时,调用ExecutorService对象的shutdown()关闭线程池
public class OneThreadPool{ public static void main(String[] args){ ExecutorService pool = Executors.newFixedThreadPool(6);//创建线程池 //使用Lambda表达式创建Runnable对象 Runnable target = ()->{ //执行代码 }; pool.submit(target);//提交线程 pool.shutdown();//关闭线程池}}

ForkJoinPool是一种特殊的线程池,支持把一个任务拆成多个小任务并行计算,再把多个小任务结果合并,是ExecutorService实现类。
ForkJoinPool commentPool():返回一个通用池,通用池状态不受shutdown()或者shutdownNow()影响
getCommentPoolParallelism()返回通用池并行级数
创建了ForkJoinPool 的实例后,调用submit(ForkJoinTask task)或者invoke(ForkJoinTask task)方法执行指定任务,ForkJoinTask代表可并行合并任务。
ForkJoinTask是一个抽象类,有两个抽象子类RecursiveAction和RecuersiveTask,RecuersiveTask代表有返回值的任务,RecursiveAction代表没有返回值的任务
下面是一个例子,使用RecuersiveTask对长度是100的数组元素值累加
class PoolTask extends RecuersiveTask<Integer>{private static final int num = 20;//每个小任务最多累加20个private int arr[];private int start;private int end;public PoolTask(int arr[],int stat,int end){this.arr = arr;this.start = start;this.end = end;}protected Integer compute(){int sum = 0;if(end-start < num){for(int i = start;i < end;i++)sum += arr[i];return sum;}else{int middle = (start + end)/2;//将大人物分解为两个小任务PoolTask left = new PoolTask(arr,start,middle);PoolTask right = new PoolTask(arr,middle,end);//并行执行两个小任务left.fork();right.fork();//两个小任务结果合并起来return left.join() + right.join();}}}public class ForkJoinPoolTest{public static void main(String[] args) throws Exception{int[] arr = new int[100];Random random = new Random;int total = 0;//初始化100个元素for(int i = 0,len = arr.lenght;i < len;i++){int tmp = random.nextInt(20);total += (arr[i] = tmp);}ForkJoinPool pool = ForkJoinPool.commonPool();//创建一个通用池Future<Integer> future = pool.submit(new PoolTask(arr,0,arr.lenght));//提交一个可分解的PoolTask任务pool.shutdown();//关闭}}


ForkJoinPool使用步骤:1.创建ForkJoinPool实例pool->2.Future.submit(Task)->3.pool.shutdown()
在ForkJoinTask中实现任务的分解和合并,分别用到了fork()和join()
RecursiveAction的用法和RecursiveTask用法大致相同,只是没有返回值
0 0
原创粉丝点击