2013-09-05 4 views
1
public class ReadFromQueue 
{ 
    order = orderFromQueue; 

    if(!Repository.ordersIdMap.containsKey(order.orderID)) 
    {  

     Platform.runLater(new Runnable() 
     { 
      @Override public void run() 
      {                  
       Repository.ordersCollection.add(order);       
      } 
     } 
     }); 
     Repository.ordersIdMap.put(order.orderID, order); 
    } 

Так привет еще раз, я сделал еще один вопрос, вызвать предыдущий .. плохо (извините) Позвольте мне вас в этом сценарии. У вас есть читатель, который отправляется в очередь и получает заказ (скажем, его объект заказа, готовый к использованию), эта вещь работает так быстро, что получает много заказов в секунду .. (Чтобы быть точным, я получаю 40 000 заказов в менее чем за минуту). У меня есть репозиторий, который является одноэлементным классом, в этом классе у меня есть orderIdMap (ConcurrentHashMap ключевого String и Order Value) и orderCollection, который является ObservableList (источником моего tableView). Я НЕ МОЖЕТ добавить заказ, если он уже существует в коллекции, поэтому на моей карте я сохраняю orderId (string) в качестве ключа, так что если один и тот же порядок cames снова, я должен его обновить (код else здесь отсутствует, но есть не импортировать сейчас). Дело в том, что вызов Platform.runLater для рисования в пользовательском интерфейсе дает мне проблемы .. почему? потому что, если я пойду, чтобы получить другой заказ, и Platform.runLater еще не закончил .. заказ не создается на карте, поэтому моему «читателю» его заказ будет новым и создаст его снова (в случае, если порядок имеет тот же порядокId), поэтому я получаю один и тот же порядок снова и снова. Я должен сказать, что несколько раз его достаточно быстро и порядок получает обновление .. но в большинстве случаев слишком медленно, и порядок его создания снова , Я также попытался установить «Repository.ordersIdMap.put (order.orderID, order)»; рядом с условием if .. таким образом, карта будет иметь ключ независимо от того, что..BUT все еще не работает (почему ..? dunno) .. Также, если я не использую platform.runlater ..its работает но я получаю много исключений NullPointersException .. потому что я пытаюсь обновить интерфейс, чтобы быстро .. я думаю .. любой ответ полезен !! .. СПАСИБО! и извините за мой английский.Platform.runLater, слишком медленно для обработки большого количества задач

EDIT: это весь код .. execRpt - это «маленький заказ», и из этого я могу создать более крупный заказ. Я получаю много execRpt, а затем создаю заказы .. если в заказе есть обновление ..если не добавлять его, но он не работает при обновлении (несколько раз) и просто добавляет порядок, как если бы он был новым.

package com.larrainvial.trading.trademonitor.listeners; 

import com.larrainvial.trading.emp.Controller; 
import com.larrainvial.trading.trademonitor.Repository; 
import com.larrainvial.trading.emp.Event; 
import com.larrainvial.trading.emp.Listener; 
import com.larrainvial.trading.fix44.events.ReceivedExecutionReportEvent; 
import com.larrainvial.trading.trademonitor.events.CalculatePositionsEvent; 
import com.larrainvial.trading.trademonitor.vo.ExecRptVo; 
import com.larrainvial.trading.trademonitor.vo.OrderVo; 
import javafx.application.Platform; 
import javafx.concurrent.Task; 
import quickfix.FieldNotFound; 
import quickfix.fix44.ExecutionReport; 

public class ReceivedExecutionReportToMonitorListener implements Listener 
{ 
    private OrderVo orderVo;   
    private String ordStatus = ""; 
    private String transactTime = ""; 
    private String text = ""; 
    private int qty = 0; 
    private int cumQty = 0; 
    private int lastQty = 0; 
    private int leavesQty = 0; 
    private double price = 0; 
    private double avgPx = 0; 
    private double lastPx = 0; 

    @Override 
    public void eventOccurred(Event event) 
    { 
     ExecutionReport executionReport = ((ReceivedExecutionReportEvent)event).message; 
     try 
     {    
      String settlType = ""; 
      String orderID = executionReport.isSetOrderID()? String.valueOf(executionReport.getOrderID().getValue()) : ""; 
      String execID = executionReport.isSetExecID()? String.valueOf(executionReport.getExecID().getValue()) : ""; 
      String execType = executionReport.isSetExecType()? String.valueOf(executionReport.getExecType().getValue()) : "";    
      String clOrdID = executionReport.isSetClOrdID()? String.valueOf(executionReport.getClOrdID().getValue()) : "";    
      String clOrdLinkID = executionReport.isSetClOrdLinkID()? String.valueOf(executionReport.getClOrdLinkID().getValue()) : "";    
      transactTime = executionReport.isSetTransactTime() ? String.valueOf(executionReport.getTransactTime().getValue()) : ""; 
      text = executionReport.isSetText() ? executionReport.getText().getValue().toString() : ""; 
      String tif = executionReport.isSetTimeInForce() ? String.valueOf(executionReport.getTimeInForce().getValue()) : ""; 
      String handlInst = executionReport.isSetHandlInst() ? String.valueOf(executionReport.getHandlInst().getValue()) : "";  
      String securityExchange = executionReport.isSetSecurityExchange()? String.valueOf(executionReport.getSecurityExchange().getValue()) : "";  
      String orderType = executionReport.isSetOrdType()? String.valueOf(executionReport.getOrdType().getValue()) : "";     
      String account = executionReport.isSetAccount() ? String.valueOf(executionReport.getAccount().getValue()) : "None"; 
      ordStatus = String.valueOf(executionReport.getOrdStatus().getValue());    
      lastPx = executionReport.isSetLastPx()? executionReport.getLastPx().getValue() : 0; 
      price = executionReport.isSetPrice()? executionReport.getPrice().getValue() : 0; 
      avgPx = executionReport.isSetAvgPx()? executionReport.getAvgPx().getValue() : 0;    
      lastQty = executionReport.isSetLastQty()? (int)executionReport.getLastQty().getValue() : 0; 
      leavesQty = executionReport.isSetLeavesQty()? (int)executionReport.getLeavesQty().getValue() : 0; 
      cumQty = executionReport.isSetCumQty()? (int)executionReport.getCumQty().getValue() : 0; 
      qty = executionReport.isSetOrderQty()? (int)executionReport.getOrderQty().getValue() : 0;    

      ExecRptVo execRpt = new ExecRptVo(orderID, 
              execID, 
              execType, 
              ordStatus, 
              clOrdID, 
              clOrdLinkID, 
              securityExchange, 
              String.valueOf(executionReport.getSide().getValue()), 
              qty, 
              lastQty, 
              leavesQty, 
              cumQty, 
              executionReport.getSymbol().getValue().toString(), 
              orderType, 
              price, 
              lastPx, 
              avgPx, 
              tif, 
              "", 
              handlInst, 
              securityExchange, 
              settlType, 
              account, 
              text, 
              transactTime); 

      orderVo = new OrderVo(execRpt); 
      OrderVo orderExist = Repository.ordersIdMap.putIfAbsent(orderID, orderVo); 

      if(orderExist == null) 
      {                        
       Platform.runLater(new Runnable() 
       { 
        @Override public void run() 
        { 
         Repository.ordersCollection.add(orderVo); 
        }           
       }); 
      }   
      else 
      {    
       Repository.ordersIdMap.get(orderID).price.set(price); 
       Repository.ordersIdMap.get(orderID).qty.set(qty); 
       Repository.ordersIdMap.get(orderID).ordStatus.set(ordStatus); 
       Repository.ordersIdMap.get(orderID).transactTime.set(transactTime); 
       Repository.ordersIdMap.get(orderID).text.set(text); 

       if(avgPx > 0) 
        Repository.ordersIdMap.get(orderID).avgPx.set(avgPx); 
       if(cumQty > 0) 
        Repository.ordersIdMap.get(orderID).cumQty.set(cumQty); 
       if(lastQty > 0) 
        Repository.ordersIdMap.get(orderID).lastQty.set(lastQty); 
       if(lastPx > 0) 
        Repository.ordersIdMap.get(orderID).lastPx.set(lastPx); 
       if(leavesQty > 0) 
        Repository.ordersIdMap.get(orderID).leavesQty.set(leavesQty); 
       if(ordStatus.equals("8")) 
        Repository.ordersIdMap.get(orderID).rejected.set("1"); 

       Repository.ordersIdMap.get(orderID).execRpts.add(execRpt);        
      }    
      if(execType.equals("1") || execType.equals("2") || execType.equals("F")) 
      {        
       CalculatePositionsEvent calculatePositionsEvent = new CalculatePositionsEvent(execRpt); 
       Controller.dispatchEvent(calculatePositionsEvent);     
      } 
     } 
     catch (FieldNotFound ex) 
     { 
      ex.printStackTrace(); 
     } 
     catch (Exception ex) 
     { 
      ex.printStackTrace(); 
     } 
    } 
} 
+0

Вопросы, подобные этому, заставляют меня желать слишком специфической закрытой классификации. – Gray

+1

Ваш английский кажется прекрасным, но я все еще не понимаю, о чем вы спрашиваете. – pamphlet

+0

Его трудно объяснить .. но основная проблема в этом .. заключается в том, что я не могу повторить заказы на orderCollection .., но условие if не работает всегда .. Иногда ключ orderId не существует (когда он должен существовать) в hashMap, и это странно. Потому что код, который, я думаю, в порядке. –

ответ

2

Одна из проблем в вашем коде заключается в том, что у вас есть шаблон check-then-act, который не является атомарным. Один из способов было бы что-то вроде:

order = orderFromQueue; 
Order alreadyInMap = Repository.ordersIdMap.putIfAbsent(order.orderID, order); 

if(alreadyInMap == null) { //it really is a new order 
    Platform.runLater(new Runnable() { 
     @Override public void run() { 
      Repository.ordersCollection.add(order); 
     } 
    }); 
} 

Также отметим, что «причина, если я иду, чтобы получить еще один заказ и Platform.runLater не закончил .. заказ не получает создан на карте» не имеет смысла: когда вы вызываете Platform.runLater(), runnable помещается в очередь, но выполняется асинхронно (если ваш метод уже не работает в потоке FX).

+1

Мне нравится пример assylias, на основе этого шаблона есть исполняемый образец, в классе [ItemProcessor здесь] (http://codetidy.com/6574), который был создан для некоторого аналогичного вопроса StackOverflow на [сложных шаблонах параллелизма JavaFX ] (http://stackoverflow.com/questions/18530493/complex-concurrency-in-javafx-using-observablelists-and-properties-from-multipl). – jewelsea

+0

Приветствую вас обоих и благодарю вас за ответ. Я пробовал это, но все еще не работает, почему ?, я не знаю, как это происходит, но иногда «ужеInmap» возвращает null, когда заказ уже существует .. как это может произойти? я действительно этого не понимаю .. потому что я уже добавил порядок в методе putIfAbsent. У меня нет объяснения этого, я просто не понимаю, потому что кажется невозможным, но он делает, я хочу плакать .. –

+0

'ужеInMap' всегда будет null, если заказ уже существует. Можете ли вы уточнить, что «не работает»? – assylias

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