Java线程(二)线程池

原创 2016年08月31日 10:16:35
系统启动一个新线程成本很高,使用线程池能很好的提高性能。尤其当需要创建大量的生存周期很短的线程时,更应该考虑线程池。
线程池在系统启动时会创建大量空闲的线程,将一个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用法大致相同,只是没有返回值
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

java线程、线程池、xml解析入门

  • 2012年08月17日 12:08
  • 2.3MB
  • 下载

Java并发(二)——线程相关类与线程池

第六部分 线程相关类6.1 继承关系Executor接口-

Java线程池,线程中断

在java中的线程池可以更加灵活的控制线程的生命周期,而且可以复用处于空闲状态的线程,更加省资源 其他的就不介绍了,介绍下: - newSingleThreadExecutor;这是一个...

线程并发线程池

  • 2014年08月27日 19:36
  • 13.38MB
  • 下载

Java线程:新特征-线程池

Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利。为了编写高效稳定可靠的多线程程序...

C#线程池 所有线程运行完毕

  • 2012年07月31日 23:59
  • 23KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java线程(二)线程池
举报原因:
原因补充:

(最多只允许输入30个字)