2017-02-02 12 views
0

スレッドは常に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(); 

executorがこれを行い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私は両方のリストが空でないとinitAndRunExecutionが呼び出されていることを確実に知るしかし、注文執行runメソッドが呼び出されていない....

+0

'firstBuysList.get(0)'の代わりに 'firstBuysList.remove(0)'を試してみてください。 firstSellsと同じです... 'get'は要素を削除しません。だからあなたは非常に高い頻度で同じ2つの要素を提出する無限ループにいます。だから私はあなたのエグゼキュータスレッドが決してスケジュールされることはないと思う。 – Fildor

+0

@Fildor、よく働かないでください... – kitsuneFox

+0

ああ、私は大丈夫です。コメントを削除しました。これらのリストをどのように埋めるのですか? – JIV

答えて

1

、と呼ばれている、しかし、注文執行runメソッドではありません呼び出されている....

私はあなたのfirstSellsListfirstBuysListがコレクションを同期されていないので、これは問題であると思われます。私は他のスレッドがそれらのリストに追加していると思うが、あなたのOrderExecutionThreadはメモリの更新を見ることはないので、空のリストを永遠に見ることができる。スレッド間でデータを共有するたびに、更新の公開方法とスレッドキャッシュメモリの更新方法を心配する必要があります。

@Fildorがコメントに言及しているように、1つの解決策はListの代わりにBlockingQueueを使用することです。 BlockQueue(たとえばLinkedBlockingQueue)は同期クラスであるため、これはメモリ共有を処理します。別の利点は、エントリを監視するためにスピンループを行う必要がないことです。リストは注文を実行する前にエントリを取得するまでは待機します

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

たとえば、あなたOrderExecutionThreadのような何かを行う可能性があります。

関連する問題