线程池的拒绝策略


一、线程池

线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象;

线程池的优点

1.提高响应速度,可以提前启动所有的核心线程,任务过了就可以直接执行
2.降低资源消耗,不用频繁创建和销毁线程
3.提高线程的可管理性


二、Java内置线程池

通过查看java中的ThreadPoolExecutor的源码
ThreadPoolExecutor源码图


线程池执行任务的流程,直到什么时候会启动拒绝策略:


a.每过来一个任务会启动一个线程去执行
b.当核心线程数用完后,会把新来的任务存入阻塞队列中
c.阻塞队列存满后,会再启动超过核心线程数量到最大线程数量之间的线程
d.当线程的数量达到最大线程数量,再来任务就启动拒绝策略


三、拒绝策略

策略处理方式
AbortPolicy直接抛出异常
DiscardPolicy丢弃当前被拒绝的任务(不抛出异常)
DiscardOldestPolicy将工作队列中最早的任务丢弃,去执行新的任务
CallerRunsPolicy交给调用线程池的线程处理

AbortPolicy

直接抛出异常:线程池默认的拒绝策略,在任务不能再提交的时候,抛出异常,
及时反馈程序运行状态。如果是比较关键的业务,推荐使用此拒绝策略,这样子在系统
不能承载更大的并发量的时候,能够及时的通过异常发现。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class csdn {
		public static void main(String[] args) throws Exception{
	        //核心线程数
			int corePoolSize = 3;
			//最大线程数
	        int maximumPoolSize = 8;
	        long keepAliveTime = 5;
            //创建阻塞队列队列为10
	        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(10);
            //调用AbortPoilcy
	        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
              //创建线程池
	        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, 
	        			maximumPoolSize, 
	        			keepAliveTime, 
	        			TimeUnit.SECONDS, 
	        			workQueue,
	        		    handler);
	        Runnable r = () -> System.out.println(Thread.currentThread().getName() + " is running");
	        for(int i=0; i<100; i++) {
	            try {
	                executor.execute(r);
	            } catch (Exception e) {
	                e.printStackTrace();
	            }
	        }
            //关闭线程池
	        executor.shutdown();
	    }
	}

AbortPolicy

DiscardPolicy

丢弃当前被拒绝的任务(不抛出异常) 拒绝任务时不通知
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class csdn {
		public static void main(String[] args) throws Exception{
	        //核心线程数
			int corePoolSize = 3;
			//最大线程数
	        int maximumPoolSize = 8;
	        long keepAliveTime = 5;
            //创建阻塞队列队列为10
	        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(10);
            //调用AbortPoilcy
	        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
              //创建线程池
	        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
	        Runnable r = () -> System.out.println(Thread.currentThread().getName() + " is running");
	        for(int i=0; i<100; i++) {
	            try {
	                executor.execute(r);
	            } catch (Exception e) {
	                e.printStackTrace();
	            }
	        }
            //关闭线程池
	        executor.shutdown();
	    }
	}

DiscardPolicy

DiscardOldestPolicy

将工作队列中最早的任务丢弃,去执行新的任务
抛弃的任务通常是队列的头结点,也就是存活时间最长的任务。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class csdn {
		public static void main(String[] args) throws Exception{
	        //核心线程数
			int corePoolSize = 3;
			//最大线程数
	        int maximumPoolSize = 8;
	        long keepAliveTime = 5;
            //创建阻塞队列队列为10
	        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(10);
            //调用AbortPoilcy
	        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
              //创建线程池
	        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
	        Runnable r = () -> System.out.println(Thread.currentThread().getName() + " is running");
	        for(int i=0; i<100; i++) {
	            try {
	                executor.execute(r);
	            } catch (Exception e) {
	                e.printStackTrace();
	            }
	        }
            //关闭线程池
	        executor.shutdown();
	    }
	}

DiscardOldestPolicy

CallerRunsPolicy

交给调用线程池的线程处理
线程池没能力执行任务,就把这个任务交于提交任务的线程执行
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class csdn {
		public static void main(String[] args) throws Exception{
	        //核心线程数
			int corePoolSize = 3;
			//最大线程数
	        int maximumPoolSize = 8;
	        long keepAliveTime = 5;
            //创建阻塞队列队列为10
	        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(10);
            //调用AbortPoilcy
	        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
              //创建线程池
	        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
	        Runnable r = () -> System.out.println(Thread.currentThread().getName() + " is running");
	        for(int i=0; i<100; i++) {
	            try {
	                executor.execute(r);
	            } catch (Exception e) {
	                e.printStackTrace();
	            }
	        }
            //关闭线程池
	        executor.shutdown();
	    }
	}

CallerRunsPolicy
总结:
四种拒绝策略是相互独立无关的,选择何种策略去执行,还得结合具体的业务场景。实际工作中,一般直接使用 ExecutorService 的时候,默认使用的是AbortPolicy 策略。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值