线程池拒绝策略+超时机制

线程池拒绝策略

在Java中,Executor线程池是通过ThreadPoolExecutor类实现的,你可以通过自定义拒绝策略来处理当线程池无法接受新任务时的情况。拒绝策略定义了当任务无法提交给线程池时应该采取的动作。

要自定义拒绝策略,你需要创建一个实现了RejectedExecutionHandler接口的类,并实现rejectedExecution()方法。该方法会在任务被拒绝时被调用,你可以在该方法中定义自己的逻辑来处理拒绝的任务。

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

public class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        // 自定义处理逻辑,例如记录日志或抛出异常
        System.out.println("任务被拒绝: " + r.toString());

        // 可以选择抛出异常或者其他处理方式
        throw new RejectedExecutionException("任务被拒绝: " + r.toString());
    }
}

然后,在创建线程池时,使用你自定义的拒绝策略:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class Main {
    public static void main(String[] args) {
        int threadPoolSize = 10;
        int maxThreadPoolSize = 20;
        long keepAliveTime = 60L;

        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                threadPoolSize,
                maxThreadPoolSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(100),
                new CustomRejectedExecutionHandler()
        );

        // 执行任务...
        executor.execute(new MyTask());
    }
}

在上述示例中,当任务被拒绝时,会打印一条消息并抛出RejectedExecutionException异常。你可以根据需要自定义拒绝策略的处理逻辑,例如记录日志、进行特定操作或选择不同的异常处理方式。

线程超时机制+cancel线程

在Java中,线程的超时时间是指在执行过程中限制线程的最大执行时间,如果线程在指定的时间内未能完成任务,则中断线程的执行。

一种常见的方式是在任务执行前使用Future和get()方法来设置线程的最大超时时间。get()方法可以指定一个超时时间,如果任务在该时间内未能完成,则会抛出TimeoutException异常。

import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        Callable<String> task = () -> {
            // 模拟需要耗时的任务
            Thread.sleep(5000);
            return "任务执行完成";
        };

        Future<String> future = executor.submit(task);

        try {
            String result = future.get(3, TimeUnit.SECONDS); // 设置超时时间为3秒
            System.out.println(result);
        } catch (TimeoutException e) {
            // 超时异常处理
            System.out.println("任务执行超时");
            future.cancel(true); // 中断线程的执行
        } catch (InterruptedException | ExecutionException e) {
            // 其他异常处理
            e.printStackTrace();
        }

        executor.shutdown();
    }
}

在上述示例中,创建了一个单线程的线程池,并提交了一个耗时的任务。使用future.get(3, TimeUnit.SECONDS)来设置超时时间为3秒。如果任务在3秒内未能完成,则会抛出TimeoutException异常。在异常处理中可以针对超时进行相应的操作,如中断线程的执行。

需要注意的是,在捕获到TimeoutException异常后,可以调用future.cancel(true)来中断线程的执行,参数true表示中断执行线程。这样可以提前终止任务的执行,但需要注意任务本身需要支持中断操作,否则中断操作可能无效。

另外,在使用ExecutorService时,记得在适当的时候调用shutdown()方法来关闭线程池,以确保资源正确释放。

ForkJoinPool

如果项目采用了类似于ForkJoinPool这种jdk提供的标准线程池库

ForkJoinPool内部使用ForkJoinWorkerThreadFactory来创建线程,并使用ForkJoinWorkerThread来表示工作线程。要自定义拒绝策略,你可以实现自己的ForkJoinWorkerThreadFactory,在工厂中创建自定义的ForkJoinWorkerThread,并设置拒绝策略。

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;

public class CustomForkJoinWorkerThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
    private final RejectedExecutionHandler rejectedExecutionHandler;

    public CustomForkJoinWorkerThreadFactory(RejectedExecutionHandler rejectedExecutionHandler) {
        this.rejectedExecutionHandler = rejectedExecutionHandler;
    }

    @Override
    public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
        return new CustomForkJoinWorkerThread(pool, rejectedExecutionHandler);
    }
}

class CustomForkJoinWorkerThread extends ForkJoinWorkerThread {
    private final RejectedExecutionHandler rejectedExecutionHandler;

    protected CustomForkJoinWorkerThread(ForkJoinPool pool, RejectedExecutionHandler rejectedExecutionHandler) {
        super(pool);
        this.rejectedExecutionHandler = rejectedExecutionHandler;
    }

    @Override
    protected void onStart() {
        // 设置拒绝策略
        ThreadPoolExecutor executor = (ThreadPoolExecutor) getPool();
        executor.setRejectedExecutionHandler(rejectedExecutionHandler);
        super.onStart();
    }
}

class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        // 自定义拒绝策略的处理逻辑
        System.out.println("任务被拒绝: " + r.toString());
    }
}

public class Main {
    public static void main(String[] args) {
        RejectedExecutionHandler rejectedExecutionHandler = new CustomRejectedExecutionHandler();

        ThreadFactory threadFactory = new CustomForkJoinWorkerThreadFactory(rejectedExecutionHandler);

        ForkJoinPool forkJoinPool = new ForkJoinPool(4, threadFactory, rejectedExecutionHandler, false);

        // 执行任务...
        forkJoinPool.invoke(new MyRecursiveTask());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,线程池是一种管理线程并发执行的机制,它提供了一种更高效、资源可重用的方式来组织任务执行。控制线程池主要有以下几个方面: 1. **大小限制**:线程池会设置最大线程数(`corePoolSize` 和 `maximumPoolSize`),当工作队列满且核心线程已全部运行时,如果新的请求到来,就会拒绝新任务,直到线程池中有空闲的线程可用。 2. **工作队列**:例如使用 `LinkedBlockingQueue` 或 `ArrayBlockingQueue`,用于存放等待执行的任务。一旦队列满且所有线程都在忙碌,处理策略可以是阻塞等待、丢弃任务或者用默认处理器(如单线程)执行。 3. **线程复用**:当线程完成任务并返回到线程池时,线程并不会立即结束,而是继续待命,等待下一轮任务分配。 4. **线程调度**:线程池中的线程可以根据设置的不同策略(如轮询、优先级、定时器等)进行调度。 5. **动态调整**:有些线程池API(如`ThreadPoolExecutor`)允许通过 `setCorePoolSize`、`setMaximumPoolSize` 等方法动态调整线程池大小。 6. **超时和守护线程**:可以配置线程等待队列的任务多久后放弃,并设置是否有守护线程(当主线程结束时,这些守护线程也会自动关闭)。 常见的Java线程池工具有`java.util.concurrent.ThreadPoolExecutor`和`java.util.concurrent.ExecutorService`,以及第三方库如Spring框架提供的`ThreadPoolTaskExecutor`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值