-
为什么要用线程池
1.降低资源消耗:通过重用已经创建的线程来降低线程创建和销毁的消耗
2.提高响应速度:任务到达时不需要等待线程创建就可以立即执行
3.提高线程的可管理性:线程池可以统一管理、分配、调优和监控 -
线程的四种创建方式
1.Executors.newFixedThreadPool 创建一个coreSize=maxSize=n的线程池,每个线程不限制空闲时间,一直阻塞等待任务(LinkedBlockingQueue)
2. Executors.newCachedThreadPool 创建一个coreSize=0, maxSize=Integer.MAX_VALUE, 每个线程最大空闲时间不能超过60s,否则强制退出(SynchronousQueue)
3. Executors.newSingleThreadExecutor 创建一个coreSize=maxSize=1的线程池,每个线程不限制空闲时间,一直阻塞等待任务,不存在并发,保证任务有序执行完(LinkedBlockingQueue)
4. Executors.newScheduledThreadPool 创建一个coreSize=0, maxSize=Integer.MAX_VALUE,每个线程空闲时间设置0,否则强制退出(DelayedWorkQueue) -
线程池的重要参数
1.allowCoreThreadTimeOut 指定核心线程是否允许超时,非核心线程写死在代码里面一定是有空闲时间限制的boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
2 .keepAliveTime 指定核心线程或者非核心线程的最大空闲时间
3.corePoolSize 指定核心线程数量
4.maximumPoolSize 指定最大线程数量
5.RejectedExecutionHandler 指定使用的拒绝策略(AbortPolicy,DiscardPolicy,DiscardOldestPolicy,CallerRunsPolicy)
6.ThreadFactory 指定创建线程的工厂实现 -
线程池应用----多个任务都完成做统计
//用栅栏 public class Test5 { public static void main(String[] args) throws InterruptedException, ExecutionException { CountDownLatch countDownLatch = new CountDownLatch(5); List<FutureTask> futureTaskList=new ArrayList<>(); for(int i=1;i<=100;i++) { FutureTask<Integer> integerFutureTask = new FutureTask<Integer>(new Task(i,countDownLatch)); futureTaskList.add(integerFutureTask); new Thread(integerFutureTask).start(); } countDownLatch.await(); int count=0; for (FutureTask<Integer> futureTask: futureTaskList ) { count+=futureTask.get(); } System.out.println("统计:"+count); } } class Task implements Callable<Integer> { private Integer integer; private CountDownLatch countDownLatch; public Task(Integer integer) { this.integer = integer; } public Task(Integer integer, CountDownLatch countDownLatch) { this.integer = integer; this.countDownLatch = countDownLatch; } @Override public Integer call() throws Exception { countDownLatch.countDown(); return integer; } }
-
线程池应用—百万任务如何快速处理
/** * 假设一个任务消耗2毫秒,那么单线程处理10万个任务需要200秒 * 使用forkjoin,会将大任务拆成小任务,拆分的每个小任务会有一个线程处理,相当于多个线程同时处理 */ public class ForkJoinTask { public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println("开始时间:"+new Date()); ForkJoinPool forkJoinPool = new ForkJoinPool(); Long integer = forkJoinPool.submit(new Task(1L, 100000L)).get(); System.out.println("计算结果:"+integer); System.out.println("开始时间:"+new Date()); System.out.println("开始时间2:"+new Date()); Long sum=0L; Long i=1L; while (i<=100000L){ sum+=i; i++; Thread.sleep(2); } System.out.println(sum); System.out.println("开始时间2:"+new Date()); } } class Task extends RecursiveTask<Long>{ private Long start; private Long end; public Task(Long start, Long end) { this.start = start; this.end = end; } @Override protected Long compute() { Long sum=0L; boolean canCompute=(end-start)<=2; if(canCompute){ for(Long i=start;i<=end;i++){ sum+=i; try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } }else { Long middle=(start+end)/2; Task task = new Task(start, middle); Task task1 = new Task(middle + 1, end); task.fork(); task1.fork(); Long join = task.join(); Long join1 = task1.join(); sum=join+join1; } return sum; } } 开始时间:Fri Apr 24 22:28:16 CST 2020 计算结果:5000050000 开始时间:Fri Apr 24 22:28:38 CST 2020 开始时间2:Fri Apr 24 22:28:38 CST 2020 5000050000 开始时间2:Fri Apr 24 22:32:47 CST 2020
-
CountDownLatch和ForkJoinTask对比
1.都可以通过阻塞,等到所有任务执行完再统计结果
2.CountDownLatch没有任务切分功能,ForkJoinTask可以有任务切分功能
3.CountDownLatch线程开销大,ForkJoinTask一个线程可以处理一批任务
4.大部分还是使用ForkJoinTask,功能完善
常见问题之线程池
猜你喜欢
转载自blog.csdn.net/weixin_38312719/article/details/105512982
今日推荐
周排行