您的位置:

线程池拒绝策略详解

一、基本概念

线程池是在实际项目中经常使用的一种技术,它可以提高程序的效率,同时也可以避免频繁的线程创建和销毁的开销。线程池中包含着若干个线程,这些线程能够接收程序传递过来的任务,并按照一定的策略来执行这些任务。在线程池中,拒绝策略用于处理当线程池中的线程资源不足时,向调用者返回一种拒绝策略,从而防止任务队列中的任务出现无法被处理的情况。

二、线程池拒绝策略类型

Java中定义了四种拒绝策略,在使用线程池的时候可以根据实际情况选择合适的拒绝策略,避免任务队列中的任务无法被处理。下面我们来逐一介绍这四种线程池拒绝策略类型:

1. CallerRunsPolicy

如果线程池中的线程已经达到最大并发数,而且等待队列已经被填满,那么新提交的任务将在调用这个线程池的execute()方法的线程中执行,也就是说,这个任务是会在提交这个任务的线程中执行的。这种情况下,由于任务是在调用者线程中执行,因此执行效率可能会受到一定的影响。

public class CallerRunsPolicy implements RejectedExecutionHandler {
  public CallerRunsPolicy() { }
  public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
      r.run();
    }
  }
}

2. AbortPolicy

这是线程池的默认拒绝策略。如果线程池中的线程已经达到最大并发数,而且等待队列已经被填满,那么新提交的任务将会被抛弃,并抛出RejectedExecutionException异常。

public class AbortPolicy implements RejectedExecutionHandler {
  public AbortPolicy() { }
  public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString());
  }
}

3. DiscardPolicy

这种策略会直接将新提交的任务抛弃,不做任何处理。如果队列满了,那么后续的任务就会被忽略掉。

public class DiscardPolicy implements RejectedExecutionHandler {
  public DiscardPolicy() { }
  public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
  }
}

4. DiscardOldestPolicy

这种策略会将最早提交的任务从队列中移除,然后尝试再次执行新提交的任务。

public class DiscardOldestPolicy implements RejectedExecutionHandler {
  public DiscardOldestPolicy() { }
  public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
      e.getQueue().poll();
      e.execute(r);
    }
  }
}

三、自定义拒绝策略

如果以上四种拒绝策略不能够满足实际需求,我们可以自己定义一种新的拒绝策略。在定义新的拒绝策略时,我们只需要实现RejectedExecutionHandler接口,并重写其中的rejectedExecution方法就可以了。

public class CustomPolicy implements RejectedExecutionHandler {
  public CustomPolicy() { }
  public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    // 自定义处理逻辑
  }
}

四、总结

线程池是一种非常常用的技术,它可以避免频繁的线程创建和销毁的开销,提高程序的效率。在使用线程池时,线程池拒绝策略起着非常重要的作用,能够防止任务队列中的任务出现无法被处理的情况。在Java中,定义了四种线程池拒绝策略类型,使用者可以根据具体的情况进行选择。同时,Java也支持自定义拒绝策略,当以上四种类型无法满足实际需求时,我们可以根据实际情况定义新的拒绝策略。