线程池的工作原理

一、任务在线程池中是如何被执行的

  

二、线程池的拒绝策略

    1) 默认的策略是AbortPolicy 当大于最大线程数后直接抛出异常

     代码实现:

    /**
     *  核心线程数1 最大线程2 任务队列大小2  采用AbortPolicy
     *  运行结果
     * 0
     * 3
     * 1
     * 2
     * Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.lwd.thread.MyRunable@77afea7d rejected from java.util.concurrent.ThreadPoolExecutor@5f8ed237[Running, pool size = 2, active threads = 0, queued tasks = 0, completed tasks = 4]
     *     at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
     *     at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
     *     at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
     *  分析: 1.当第一个任务0进入线程池,没有任务执行,创建一个线程去执行线程任务
     *        2.当的第二个任务3进入线程池,由于核心线程已经满了将3加入队列
     *        3.第三个任务1 也加入队列中
     *        4.第四个任务2到了进入,判断当前任务队列已经满了,但是小于最大线程池数,那么创建一个新的线程来执行
     *        5.后续的任务进入后,发现有都满了  那么直接抛出异常启动了拒绝策略AbortPolicy
     *
     *
     */
    public static void abortPolicy(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2),new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i < 6; i++) {
            MyRunable myRunable = new MyRunable(i);
            threadPoolExecutor.execute(myRunable);
        }
    }

实现方式:

/**
         * Always throws RejectedExecutionException.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }

 

2)CallerRunsPolicy 当没有可执行任务的线程,持有当前线程池的线程执行线程任务  会造成主线程阻塞

    /**
     * 线程池无法执行,新的任务由持有当前线程池的线程运行,缺点会造成主线程阻塞
     *
     */
    public static void callerRunsPolicy(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2),new ThreadPoolExecutor.CallerRunsPolicy());
        for (int i = 0; i < 6; i++) {
            MyRunable myRunable = new MyRunable(i);
            threadPoolExecutor.execute(myRunable);
        }
    }

3)自定义拒绝策略

    实现RejectedExecutionHandler接口 重写rejectedExecution方法 我内部采用的是创建新的线程执行线程任务

package com.lwd.thread;

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 *  自定义的拒绝策略
 */
public class MyRejectedExecutionHandle implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            new Thread(r,"我是新线程").start();
    }
}

使用自定义策略

/**
     *  采用自定义的拒绝策略
     *  运行结果:
     * 线程任务执行===========4
     * 线程任务执行===========5
     * 线程任务执行===========0
     * 线程任务执行===========3
     * 线程任务执行===========1
     * 线程任务执行===========2
     *
     */
    public static void myRejectedExecutionHandle(){

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2),new MyRejectedExecutionHandle());
        for (int i = 0; i < 6; i++) {
            MyRunable myRunable = new MyRunable(i);
            threadPoolExecutor.execute(myRunable);
        }
    }

 

 

 

 

 

 

 

 

 

 

  

posted @ 2020-10-12 15:31  liuwd  阅读(263)  评论(0编辑  收藏  举报