java线程池的阻塞策略

一、线程池的阻塞策略主要有以下几种:

AbortPolicy:这是默认阻塞策略,当线程队列和空闲线程都无法处理新任务时,新任务提交会直接抛出异常RejectedExecutionException,该异常可以由调用者捕获。

CallerRunsPolicy:这个策略会尝试调节机制,既不抛弃任务也不抛出异常,而是将某些任务回退到调用者,由调用任务的线程来执行。

DiscardPolicy:这个策略会抛弃新提交的任务,不进行处理。

DiscardOldestPolicy:这个策略会抛弃队列中最后一个任务,然后执行新进来的任务。

自定义策略:除了上面提到的四种常见的拒绝策略(AbortPolicy、CallerRunsPolicy、DiscardPolicy和DiscardOldestPolicy),您也可以通过自定义实现RejectedExecutionHandler接口来定义自己的拒绝策略。

二、策略的举例说明

这些是线程池中常见的拒绝策略,它们用于处理在线程池已满时无法接收新任务的情况。下面我会给出这4种拒绝策略的例子:

  1. AbortPolicy(默认的拒绝策略):直接抛出RejectedExecutionException异常。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class AbortPolicyExample {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(1), new ThreadPoolExecutor.AbortPolicy());

        // 提交5个任务,线程池无法处理超过1个任务,将抛出RejectedExecutionException异常
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
            });
        }

        executor.shutdown();
    }
}

在此示例中,线程池最大线程数设置为1,工作队列长度也为1。当同时提交5个任务时,第一个任务能够被执行,但对于其余的任务,线程池将抛出RejectedExecutionException异常。

  1. CallerRunsPolicy:让提交拒绝的任务在提交线程上执行。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class CallerRunsPolicyExample {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(1), new ThreadPoolExecutor.CallerRunsPolicy());

        // 提交5个任务,线程池无法处理超过1个任务,调用线程将执行剩下的4个任务
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
            });
        }

        executor.shutdown();
    }
}

在此示例中,线程池最大线程数设置为1,工作队列长度也为1。当同时提交5个任务时,第一个任务能够被执行,但对于其余的任务,线程池将不会抛出异常,而是将任务交由提交线程来执行。

  1. DiscardPolicy:直接丢弃无法处理的任务,不提供任何反馈。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class DiscardPolicyExample {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(1), new ThreadPoolExecutor.DiscardPolicy());

        // 提交5个任务,线程池无法处理超过1个任务,多余的任务将被直接丢弃
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
            });
        }

        executor.shutdown();
    }
}

在此示例中,线程池最大线程数设置为1,工作队列长度也为1。当同时提交5个任务时,第一个任务能够被执行,但对于其余的任务,线程池将直接丢弃它们。

  1. DiscardOldestPolicy:丢弃最旧的任务,并尝试再次提交新任务。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class DiscardOldestPolicyExample {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(1), new ThreadPoolExecutor.DiscardOldestPolicy());

        // 提交5个任务,线程池无法处理超过1个任务,多余的任务将丢弃最旧的任务
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
            });
        }

        executor.shutdown();
    }
}

是的,除了上述提到的四种常见的拒绝策略,Java中的ThreadPoolExecutor还提供了另外一种拒绝策略:DiscardPolicy。除此之外,您也可以自定义拒绝策略。
在此示例中,线程池最大线程数设置为1,工作队列长度也为1。当同时提交5个任务时,第一个任务能够被执行,但对于其余的任务,线程池将丢弃位于工作队列最前面(最旧的)的任务,并尝试再次提交新任务。

  1. 自定义拒绝策略
    要自定义拒绝策略,您需要实现RejectedExecutionHandler接口,并实现其中的rejectedExecution方法,在该方法中定义自定义的拒绝逻辑。下面是一个示例:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class CustomRejectionPolicyExample {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(1), new CustomRejectionPolicy());

        // 提交5个任务,线程池无法处理超过1个任务,使用自定义的拒绝策略处理任务
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
            });
        }

        executor.shutdown();
    }
}

// 自定义拒绝策略实现RejectedExecutionHandler接口
class CustomRejectionPolicy implements ThreadPoolExecutor.RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        if (!executor.isShutdown()) {
            // 自定义拒绝策略的处理逻辑
            System.out.println("Task rejected by custom rejection policy");
        }
    }
}

在此示例中,我们使用自定义的拒绝策略CustomRejectionPolicy来处理线程池无法处理的任务。当提交任务时,线程池无法处理超过1个任务,因此拒绝策略将被触发,执行自定义的拒绝逻辑。

通过自定义拒绝策略,您可以根据具体需求来处理无法接收的任务。您可以在rejectedExecution方法中实现自定义的处理逻辑,如记录日志、抛出异常或执行其他操作。

它们可以根据具体需求来选择适合的拒绝策略来处理线程池无法接收新任务的情况。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@zcc@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值