Thread pool of common problems

  • Why use thread pool
    1. Reduce resource consumption: reduce the consumption of thread creation and destruction by reusing the threads that have been created
    2. Improve response speed: Tasks can be executed immediately without waiting for thread creation when they arrive
    3. Improve thread management Performance: The thread pool can be managed, distributed, tuned and monitored uniformly

  • Four ways to
    create threads 1. Executors.newFixedThreadPool creates a coreSize=maxSize=n thread pool, each thread does not limit idle time, has been blocked waiting for tasks (LinkedBlockingQueue)
    2. Executors.newCachedThreadPool creates a coreSize=0, maxSize= Integer.MAX_VALUE, the maximum idle time of each thread cannot exceed 60s, otherwise it is forced to exit (SynchronousQueue)
    3. Executors.newSingleThreadExecutor creates a thread pool with coreSize=maxSize=1, each thread does not limit the idle time, and has been blocked waiting for tasks. Concurrency exists to ensure the orderly execution of tasks (LinkedBlockingQueue)
    4. Executors.newScheduledThreadPool creates a coreSize=0, maxSize=Integer.MAX_VALUE, and the idle time of each thread is set to 0, otherwise it is forced to exit (DelayedWorkQueue)

  • The important parameter of the thread pool
    1.allowCoreThreadTimeOut specifies whether the core thread is allowed to time out, non-core threads must have idle time restrictions in the code.

    boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
    

    2 .keepAliveTime designated core or non-core thread thread idle time of maximum
    number of 3.corePoolSize designated core thread
    4.maximumPoolSize specify the maximum number of threads
    deny policy (AbortPolicy, DiscardPolicy, DiscardOldestPolicy, CallerRunsPolicy ) 5.RejectedExecutionHandler specify the use of
    6.ThreadFactory specify the creation Thread factory implementation

  • Thread pool application-multiple tasks are completed for statistics

    //用栅栏
    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;
        }
    }
    
  • Thread pool application-how to handle millions of tasks quickly

    /**
     * 假设一个任务消耗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
    
  • Comparison of CountDownLatch and ForkJoinTask
    1. Both can be blocked and wait until all tasks are executed before counting the results.
    2. CountDownLatch does not have task segmentation function, ForkJoinTask can have task segmentation function
    3. CountDownLatch thread overhead is high, ForkJoinTask one thread can handle a batch of tasks
    4. Most of them still use ForkJoinTask, with perfect functions

Guess you like

Origin blog.csdn.net/weixin_38312719/article/details/105512982
Recommended