java - 如何管理ThreadPoolTask​​Executor来阻止某些请求

标签 java multithreading threadpool

我们拥有先进的人力资源系统,该系统有一项服务计算员工出勤率,如果计算员工(X,Y,Z),它必须遵循以下内容,它会打开3个线程并并行计算,但如果请求计算员工数据X 在上一次计算结束之前再次必须推迟,直到上一个线程计算员工 X 的数据完成。

    ScheduleWeekAttendanceBean scheduleWeekAttendanceBean = null;
    ThreadPoolExecutor threadPoolExecutor = employeeThreadPoolExecutorMap.get(employmentBean.id);
    if (threadPoolExecutor == null || threadPoolExecutor.isTerminating() || threadPoolExecutor.isTerminated()) {
        threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new RejectedExecutionHandlerImpl());
        employeeThreadPoolExecutorMap.put(employmentBean.id, threadPoolExecutor);

        ThreadPoolTaskExecutorMonitorService threadPoolTaskExecutorMonitorService = new ThreadPoolTaskExecutorMonitorService(threadPoolExecutor, "#" + employmentBean.employeeId);
        Thread thread = new Thread(threadPoolTaskExecutorMonitorService);
        thread.start();
    }

    AttendanceBuilder attendanceBuilder = (AttendanceBuilder) AppContext.getBean("attendanceBuilder");
    attendanceBuilder.initialize(employmentBean, selectedDate);
    Future<ScheduleWeekAttendanceBean> future = threadPoolExecutor.submit(attendanceBuilder);
    scheduleWeekAttendanceBean = future.get();

    if (threadPoolExecutor.getActiveCount() == 0) {
        employeeThreadPoolExecutorMap.remove(employmentBean.id);
        threadPoolExecutor.shutdownNow();
    }

    return scheduleWeekAttendanceBean;

这里发生了什么,它一一处理它们,我需要实现这个逻辑,但只有在 map 中存在相同的员工时才会阻止。

最佳答案

为每个员工 ID 创建单独的 ThreadPoolExecutor 会产生开销。每个ThreadPoolExecutor都包含一个Thread,该线程会消耗大量内存,这可能会导致致命的OutOfMemoryError。因此,我建议改用 SerialExecutor,这在 java.util.concurrent.Executor 的文档中进行了描述。 。 SerialExecutor 不包含线程,而是使用外部 Executor。您可以为所有 SerialExecutor 创建单个 Executor,并调整其配置(线程数)。由于 SerialExecutor 很小,因此您可以将它们全部永久保留在 employeeThreadPoolExecutorMap 中。

另一种方法是使用 Actors而不是执行者。 Actor 可以被视为专门的 Executor,旨在处理特定任务(消息)。你可以使用Akka actor,或者我的Simple Actor .

关于java - 如何管理ThreadPoolTask​​Executor来阻止某些请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58890287/

相关文章:

java - 为什么 GEF 编辑器部分不显示?

java - 如何将 ArrayList 拆分为多个列表?

java - Mysql插入查询不适用于插入

java - 初学者 Java 多线程编程 : Scheduling Difference between Window and Mac

c# - ios monotouch 的 UIProgressView 跟踪下载状态

java - CompletableFuture, thenCompose 方法

java - JTable 标题未显示在 JScrollPane 中

java - newFixedThreadPool 创建了超出需要的任务

java - Android - 是否可以每毫秒至少运行一次线程更新?

tomcat - Vaadin 应用程序创建导致内存泄漏的线程