0
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 个订单不到一分钟).. 我有一个存储库,它是一个单例类,在这个类中,我有一个 ordersIdMap(键字符串和值 Order 的 ConcurrentHashMap)和一个 ObservableList(我的 tableView 的源)的 ordersCollection。如果集合中已经存在,我无法添加订单,因此在我的地图中,我将 orderId(字符串)保存为键,这样如果再次出现相同的订单,我必须更新它(else 代码不在此处,但在现在不重要)。问题是调用平台。用于绘制 UI 的 runLater 给我带来了问题.. 为什么?因为如果我去获得另一个订单并且 Platform.runLater 还没有完成.. 订单没有在地图上创建,所以对我的“读者”来说,订单是新的并再次创建(如果订单具有相同的orderId),所以我一遍又一遍地得到相同的订单..我必须说有时它足够快并且订单得到更新..但大多数时候太慢并且订单再次创建. 我也试着把“Repository.ordersIdMap.put(order.orderID, order);” 就在if条件旁边..这样地图无论如何都会有钥匙..但仍然不起作用(为什么..?不知道)..另外,如果我不使用platform.runlater ..它的作品但我得到了很多 NullPointersException ..因为我试图将 UI 更新为快速..我认为.. 任何答案都是有用的!!..谢谢!对不起我的英语。

编辑:这是整个代码.. 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();
        }
    }
}
4

1 回答 1

2

您的代码中的一个问题是您有一个非原子的检查然后行动模式。一种解决方法是:

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 线程上运行)。

于 2013-09-05T23:22:50.703 回答