简体   繁体   English

具有EJB Timer Service的Java多线程

[英]Java multithreading with EJB Timer Service

I need to pick a batch of messages (around 20 messages) every minute from database and need to process them concurrently. 我需要每分钟从数据库中选择一批消息(大约20条消息),并且需要同时处理它们。 I am using EJB timer service (Scheduler) for fetching messages from database for every minute. 我正在使用EJB计时器服务(调度程序)每分钟从数据库中获取消息。

Basically I need to pick 20-30 messages every minute and after processing these I need to send some mails. 基本上,我需要每分钟选择20到30条消息,处理这些消息后,我需要发送一些邮件。 There are few database operations involved in processing the messages. 处理消息涉及的数据库操作很少。

Can you please suggest how I can use executor service framework from java.concurrent package and how these messages will get submitted every minute? 您能否建议我如何使用java.concurrent包中的executor服务框架,以及如何每分钟提交这些消息?

Hi here is a basic example using Java's ExecutorService, CountDownLatch and CompletableFuture. 您好,这里是使用Java的ExecutorService,CountDownLatch和CompletableFuture的基本示例。 This example is just to point you out in the right direction and by no means the perfect one and it uses a lot of Java8 stuff (I assumed you are using Java8). 这个示例只是为了向您指出正确的方向,而绝不是一个完美的示例,它使用了很多Java8的东西(我假设您正在使用Java8)。 Also I am not using EJB Timer stuff, rather going with ScheduledExecutorService but you can easily swap them I guess. 另外,我不是在使用EJB Timer东西,而是与ScheduledExecutorService一起使用,但是我想您可以轻松地交换它们。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

public class BatchMessageProcessingExample {

    private static final int BATCH_SIZE = 20;

    //Having 20 here may not entirely benefit you. Chosing this number depends on a lot of stuff.
    // Its usually better to go with total number of cores you have
    private final ExecutorService pool = Executors.newFixedThreadPool(BATCH_SIZE);

    private final ScheduledExecutorService databasePool = Executors.newScheduledThreadPool(1);

    public void schedule() {
        databasePool.scheduleWithFixedDelay(() -> runBatchProcess(), 0, 1, TimeUnit.MINUTES); //Schedule the database work to execute every minute
    }

    private void runBatchProcess() {
        List<Message> taskFromDbFetch = getMessagesFromDb(); //Get stuff from the db
        CountDownLatch countDownLatch = new CountDownLatch(taskFromDbFetch.size()); //Create a latch having same size as the list

        List<Task> taskList = taskFromDbFetch.stream().map(x -> new Task(countDownLatch, x)).collect(Collectors.toList()); // Create tasks using the messages and the countdown latch

        taskList.forEach(pool::execute); //Submit them all in pool

        CompletableFuture.runAsync(() -> sendEmailAfterCompletion(countDownLatch)); //Send an email out from a separate thread
    }

    private void sendEmailAfterCompletion(CountDownLatch countDownLatch) {
        try {
            countDownLatch.await();//Await on the latch for the batch tasks to complete
            sendEmail();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void sendEmail() {
        System.out.println("Sending out an email.");
    }

    private List<Message> getMessagesFromDb() { //Get your messages from db here
        List<Message> messages = new ArrayList<>();

        for(int i = 0; i < BATCH_SIZE; i++) {
            final int taskNumber = i;
            messages.add(() -> System.out.println("I am a db message number " + taskNumber));
        }

        return messages;
    }

    class Task implements Runnable {

        private final CountDownLatch countDownLatch;

        private final Message message;

        public Task(CountDownLatch countDownLatch, Message message) {
            this.countDownLatch = countDownLatch;
            this.message = message;
        }

        @Override
        public void run() {
            message.process(); //Process the message
            countDownLatch.countDown(); //Countdown the latch
        }
    }

    interface Message {
        void process();
    }

    public static void main(String[] args) {
        new BatchMessageProcessingExample().schedule();
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM