线程执行者(十二)执行者控制被拒绝的任务

执行者控制被拒绝的任务

当你想要结束执行者的执行,你使用shutdown()方法来表明它的结束。执行者等待正在运行或等待它的执行的任务的结束,然后结束它们的执行。

如果你在shutdown()方法和执行者结束之间,提交任务给执行者,这个任务将被拒绝,因为执行者不再接收新的任务。ThreadPoolExecutor类提供一种机制,在调用shutdown()后,不接受新的任务。

在这个指南中,你将学习如何通过实现RejectedExecutionHandler,在执行者中管理拒绝任务。

准备工作…

这个指南的例子使用Eclipse IDE实现。如果你使用Eclipse或其他IDE,如NetBeans,打开它并创建一个新的Java项目。

如何做…

按以下步骤来实现的这个例子:

1.创建RejectedTaskController类,实现RejectedExecutionHandler接口。实现这个接口的rejectedExecution()方法。写入被拒绝任务的名称和执行者的名称与状态到控制台。


1 public class RejectedTaskController implements
2RejectedExecutionHandler {
3@Override
4 public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
5 System.out.printf("RejectedTaskController: The task %s has been rejected\n",r.toString());
6 System.out.printf("RejectedTaskController: %s\n",executor.toString());
7 System.out.printf("RejectedTaskController: Terminating:%s\n",executor.isTerminating());
8 System.out.printf("RejectedTaksController: Terminated:%s\n",executor.isTerminated());
9}

2.实现Task类,实现Runnable接口。


1 public class Task implements Runnable{

3.声明私有的、String类型的属性name, 用来存储任务的名称。


1 private String name;

4.实现这个类的构造器,初始化这个类的属性。


1 public Task(String name){
2 this.name=name;
3}

5.实现run()方法,写入信息到控制台,表明这个方法开始执行。


1@Override
2 public void run() {
3 System.out.println("Task "+name+": Starting");

6.等待一段随机时间。


1 try {
2 long duration=(long)(Math.random()*10);
3 System.out.printf("Task %s: ReportGenerator: Generating a report during %d seconds\n",name,duration);
4TimeUnit.SECONDS.sleep(duration);
5 } catch (InterruptedException e) {
6e.printStackTrace();
7}

7.写入信息到控制台,表明方法的结束。


1 System.out.printf("Task %s: Ending\n",name);
2}

8.重写toString()方法,返回任务的名称。


1 public String toString() {
2 return name;
3}

9.实现这个示例的主类,通过创建Main类,并实现main()方法。


1 public class Main {
2 public static void main(String[] args) {

10.创建一个RejectedTaskController对象,管理拒绝的任务。


1 RejectecTaskController controller=new RejectecTaskController();

11.使用Executors类的newCachedThreadPool()方法,创建ThreadPoolExecutor。


1ThreadPoolExecutor executor=(ThreadPoolExecutor) Executors.newCachedThreadPool();

12.建立执行者的拒绝任务控制器。


1executor.setRejectedExecutionHandler(controller);

13.创建任务并提交它们给执行者。


1 System.out.printf("Main: Starting.\n");
2 for (int i=0; i<3; i++) {
3 Task task=new Task("Task"+i);
4executor.submit(task);
5}

14.使用shutdown()方法,关闭执行者。


1 System.out.printf("Main: Shutting down the Executor.\n");
2executor.shutdown();

15.创建其他任务并提交给执行者。


1 System.out.printf("Main: Sending another Task.\n");
2 Task task=new Task("RejectedTask");
3executor.submit(task);

16.写入信息到控制台,表明程序结束。


1 System.out.println("Main: End");
2 System.out.printf("Main: End.\n");

这是如何工作的…

以下截图显示示例的执行结果:

8

你可以看出当执行者关闭时,任务被拒绝提交。RejectecTaskController将有关于任务和执行者的信息写入到控制台。

为了管理执行者控制拒绝任务,你应该实现RejectedExecutionHandler接口。该接口有带有两个参数的方法rejectedExecution():

  • Runnable对象,存储被拒绝的任务
  • Executor对象,存储拒绝任务的执行者

每个被执行者拒绝的任务都会调用这个方法。你必须使用Executor类的setRejectedExecutionHandler()方法设置拒绝任务的处理器。

不止这些…

当执行者接收任务时,会检查shutdown()是否已经被调用了。如果被调用了,它拒绝这个任务。首先,它查找 setRejectedExecutionHandler()设置的处理器。如果有一个(处理器),它调用那个类的 rejectedExecution()方法,否则,它将抛RejectedExecutionExeption异常。这是一个运行时异常,所以你不需要 用catch语句来控制它。

参见

  • 在第4章,线程执行者中的创建一个线程执行者指南
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadPoolTaskExecutor是Spring框架提供的线程池类,用于在Spring应用中执行异步任务。它是基于ThreadPoolExecutor类的封装,提供了更多的功能和配置选项。[1] 在Spring Boot中,我们可以通过在配置类中定义一个名为"asyncServiceExecutor"的Bean来创建一个ThreadPoolTaskExecutor实例。可以使用@Configuration和@EnableAsync注解来启用异步任务,并使用@Bean注解将ThreadPoolTaskExecutor定义为一个Bean。在定义Bean的方法中,我们可以设置线程池的核心线程数、最大线程数、队列容量、线程名称前缀等属性。[2] 当我们需要执行一个任务时,可以通过@Autowired注解将ThreadPoolTaskExecutor注入到需要执行任务的类中。然后,我们可以使用ThreadPoolTaskExecutor的execute()方法来提交任务线程池会自动选择一个空闲的线程来执行任务。每个线程只会执行一条任务,当任务执行完毕后,线程会返回线程池中等待下一个任务的状态。[1] 需要注意的是,如果ThreadPoolTaskExecutor的线程池已经达到最大线程数,并且队列也已满,那么新的任务将会被拒绝执行。可以通过设置RejectedExecutionHandler来定义当线程池已满时的处理策略。常见的策略包括抛出异常、丢弃任务或者在调用者所在的线程中执行任务。[2] 总结起来,Spring的ThreadPoolTaskExecutor可以用于在Spring应用中执行异步任务,每个线程只会执行一条任务。我们可以通过配置类定义一个ThreadPoolTaskExecutor的Bean,并在需要执行任务的地方注入该Bean来使用它。[1][2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值