简体   繁体   中英

Execute Runnable lambda with more than on threads using ScheduledExecutorService

I have a method start() that creates a Runnable with a lambda. Inside the method I start a ScheduledExecutorService that consumes this Runnable. I think if only 1 thread is used to perform the task, I will not have issues, but what is going to happen if I start more than thread and pass the same Runnable inside. Example code is following:

public class MessageProcessor { 
    private final ServiceA serviceA;
    private final ServiceB serviceB;
    private final ScheduledExecutorService executor;

    public MessageProcessor() {
        this.executor = Executors.newScheduledThreadPool(1);
        this.serviceA = new ServiceA();
        this.serviceB = new ServiceB();
    }

    public void start() {

        Runnable messageProcessingTask = () -> {
            try {
                List<Message> messages = serviceA.receiveMessages();
                messages.forEach(m -> {
                    boolean success = serviceB.doSomething(m);
                    if (success) serviceB.deleteMessage(m);
                    else LOG.error("failed to process the message bla bla...");
                });
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        };

        executor.scheduleWithFixedDelay(messageProcessingTask, 0, 1, TimeUnit.SECONDS);
    }

    public void stop() {
        executor.shutdown();
    }
}

What is going to happen if change the code to use 2 threads :

    public class MessageProcessor { 

        .....

        public MessageProcessor() {
            this.executor = Executors.newScheduledThreadPool(2);
            this.serviceA = new ServiceA();
            this.serviceB = new ServiceB();
        }

        public void start() {

            Runnable messageProcessingTask = () -> {
                try {
                    List<Message> messages = serviceA.receiveMessages();
                    messages.forEach(m -> {
                        boolean success = serviceB.doSomething(m);
                        if (success) serviceB.deleteMessage(m);
                        else LOG.error("failed to process the message bla bla...");
                    });
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            };

            executor.scheduleWithFixedDelay(messageProcessingTask, 0, 1, TimeUnit.SECONDS);
            executor.scheduleWithFixedDelay(messageProcessingTask, 0, 1, TimeUnit.SECONDS);
        }

        ....
    }
  1. Is this approach a bad practice?
  2. If this code lead to errors, how can I produce them?
  3. If this is a bad approach, what the best practice would be?

Thanks in advance.

What is going to happen if change the code to use 2 threads

Well, both tasks will execute with fixed delay, concurrently. They will both try to receive messages from service A, use service B to do something and delete each message they receive, and then do it again one second later.

Whether its what you want and whether serviceA and serviceB are able to process concurrent calls is unknown, so it's up to you to decide.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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