java - 使用 ScheduledExecutorService 在多个线程上执行 Runnable lambda

标签 java multithreading lambda executorservice scheduledexecutorservice

我有一个方法start(),它使用 lambda 创建一个 Runnable。在该方法中,我启动了一个消耗此 Runnable 的 ScheduledExecutorService。我认为如果只使用 1 个线程来执行任务,我不会遇到问题,但是如果我启动多个线程并在内部传递相同的 Runnable 会发生什么。示例代码如下:

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();
    }
}

如果将代码更改为使用 2 个线程会发生什么:

    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. 这种方法是不好的做法吗?
  2. 如果此代码导致错误,我该如何产生错误?
  3. 如果这是一个不好的方法,那么最佳实践是什么?

提前致谢。

最佳答案

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

嗯,这两个任务将以固定延迟同时执行。他们都会尝试从服务 A 接收消息,使用服务 B 执行某些操作并删除收到的每条消息,然后在一秒后再次执行此操作。

是否是您想要的以及serviceA和serviceB是否能够处理并发调用都是未知的,因此由您决定。

关于java - 使用 ScheduledExecutorService 在多个线程上执行 Runnable lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38369808/

相关文章:

java - Spring-Boot:使用 Redis 作为 Session Store 时出现异常

c# - 如何在新线程上运行任务并立即返回给调用者?

c++ - 将 Boost 适配器与 C++11 lambda 配合使用

java - 优化 : Painting synchronization

c# - 以原子方式从 ConcurrentQueue 中获取所有内容

python - 必须有更好的方法来获取这个字典列表的平均值和中位数

python - 将键/值对的 Pyspark RDD 解析为 .csv 格式

java - jackson- 对象列表 com.fasterxml.jackson.core.io.JsonEOFException : Unexpected end-of-input in field name?

java - CloudSim迁移: allocation and selection policies examples在哪里

java - 在算术中避免 BigInteger 类/大数