1

У меня есть метод start(), который создает Runnable с лямбдой. Внутри метода я запускаю ScheduledExecutorService, который использует этот Runnable. Я думаю, если для выполнения задачи используется только 1 поток, у меня не будет проблем, но что произойдет, если я начну больше, чем поток, и передаю тот же Runnable внутри. Пример кода выглядит следующим образом:Выполнять Runnable лямбда с более чем на потоки, используя ScheduledExecutorService

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. Если это плохой подход, какова будет лучшая практика?

Заранее спасибо.

+0

Будет ли два вызова 'serviceA.receiveMessages()' возвращать тот же (или перекрывающий) список сообщений или отдельных? – Fildor

+0

'serviceA.receiveMessages()' возвращает пакет из 10 сообщений из очереди сообщений, разные сообщения каждый раз. Списки не пересекаются друг с другом. – Angelos

+0

Тогда это не должно быть проблемой. – Fildor

ответ

0

Что произойдет, если изменить код, чтобы использовать 2 темы

Ну, обе задачи будут выполняться с фиксированной задержкой, одновременно. Они будут пытаться получать сообщения из службы A, использовать службу B, чтобы что-то сделать, и удалить каждое полученное сообщение, а затем сделать это через секунду.

Независимо от того, что вам нужно, и могут ли службы A и serviceB обрабатывать одновременные вызовы, неизвестно, поэтому вам решать.

+0

Спасибо за ваш ответ. Кажется, что он работает, когда я увеличиваю количество потоков, я не могу доказать это с научной точки зрения. Я буду следить за поведением и посмотреть, как это происходит. – Angelos

Смежные вопросы