我有一个方法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);
}
....
}
- 这种方法是不好的做法吗?
- 如果此代码导致错误,我该如何产生错误?
- 如果这是一个不好的方法,那么最佳实践是什么?
提前致谢。
最佳答案
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/