Java线程(二)线程池

系统启动一个新线程成本很高,使用线程池能很好的提高性能。尤其当需要创建大量的生存周期很短的线程时,更应该考虑线程池。
线程池在系统启动时会创建大量空闲的线程,将一个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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值