2017-02-02 3 views
0

У меня есть Thread, который работает всегда с циклом while(true), и в основном все, что он делает, это добавлять Runnable к исполнителям.исполнитель не выполняет потоки из основной темы

OrderExecutionThread:

public class OrderExecutionThread extends Thread implements Runnable { 
    final private static int ORDER_EXEC_THREADS_NUMBER = 10; 
    private boolean running = true; 
    private boolean flag = true; 

    private List<Order> firstSellsList = new ArrayList<>(); 
    private List<Order> secondSellsList = new ArrayList<>(); 

    private ManagedDataSource managedDataSource; 
    private ExecutorService executorService; 

    public OrderExecutionThread(ManagedDataSource managedDataSource) { 
     this.managedDataSource = managedDataSource; 
     this.executorService = Executors.newFixedThreadPool(ORDER_EXEC_THREADS_NUMBER); 
    } 

@Override 
    public void run() { 
     while (running) { 
      if (!firstSellsList.isEmpty() && !firstBuysList.isEmpty()) { 
       initAndRunExecution(firstBuysList.get(0), firstSellsList.get(0)); 
     } 

    } 

    private void initAndRunExecution(Order buy, Order sell) { 
     executorService.submit(new OrderExecution(buy, sell, managedDataSource)); 
    } 
} 

Я бегу эту тему Делая это в моем главном классе:

new Thread(orderExecutionThread).start(); 

Исполнитель предполагают, чтобы выполнить OrderExecution runnable объект, который делает это:

@Override 
    public void run() { 
     try { 
      connection = managedDataSource.getConnection(); 
      makeExecution(sell, buy); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       if (!connection.isClosed()) 
        connection.close(); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
     } 

    } 

Я точно знаю, что оба списка не пусты, а initAndRunExecution, однако метод запуска исполнения заказа не вызывается ....

+0

Попробуйте 'firstBuysList.remove (0)' вместо 'firstBuysList.get (0)'. То же самое для firstSells ... 'get' не удаляет элемент. Таким образом, вы находитесь в бесконечной петле, представляющей те же самые два элемента на очень высокой частоте. Поэтому я подозреваю, что ваши потоки Executor просто никогда не планируются. – Fildor

+0

@ Фильтр, удалите тоже не работает ... – kitsuneFox

+0

О, я вижу хорошо. Убрал мой комментарий. Как вы заполняете эти списки? – JIV

ответ

1

Я точно знаю, что оба списка не пусты и вызывается initAndRunExecution, однако метод выполнения выполнения заказа не является называют ....

Я подозреваю, что это проблема, потому что ваш firstSellsList и firstBuysList не синхронизированные коллекции. Я подозреваю, что другие потоки добавляют к этим спискам, но ваш OrderExecutionThread никогда не видит обновления памяти, поэтому просто закручивает навсегда просмотр пустых списков. Всякий раз, когда вы обмениваетесь данными между потоками, вам нужно беспокоиться о том, как будут публиковаться обновления и как будет обновляться кэш-память потоков.

Как @Fildor упоминает в комментариях, одним из решений было бы использовать BlockingQueue s вместо ваших List. BlockQueue (например, LinkedBlockingQueue) - это синхронизированный класс, поэтому он заботится о совместном использовании памяти. Альтернативным преимуществом является то, что вам не нужно делать спин-петлю для просмотра записей.

Например, ваш OrderExecutionThread может сделать что-то вроде:

private final BlockingQueue<Order> firstBuys = new LinkedBlockingQueue<>(); 
private final BlockingQueue<Order> firstSells = new LinkedBlockingQueue<>(); 

while (!Thread.currentThread().isInterrupted()) { 
    // wait until we get a buy 
    Order buy = firstBuys.take(); 
    // wait until we get a sell 
    Order sell = firstSells.take(); 
    initAndRunExecution(buy, sell); 
} 

Это будет ждать, пока списки не получить записи перед выполнением заказов.

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