Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。
想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
6年前关闭。
嗨,我又问了一个问题,原因是上一个..不好(对不起)
让我来介绍一下这种情况。您有一个读入队列并获得订单的阅读器(让我们说它是一个订单对象,可以使用),该操作是如此之快,每秒可以收到很多订单。(准确地说,我得到40.000个订单不到一分钟)..我有一个单例类的存储库,在这个类中,我有一个ordersIdMap(键字符串和值Order的ConcurrentHashMap)和一个ObservableList的ordersCollection(我的tableView的源)。如果集合中已存在该订单,则无法添加订单,因此在我的地图中将orderId(字符串)保存为键,这样,如果再次出现同一订单,则必须更新它(否则代码不在此处,而是现在不重要)。问题是,调用Platform.runLater绘制到UI会给我带来问题。为什么?原因是如果我要再获得一个订单,而Platform.runLater尚未完成..则该订单未在地图上创建,因此对我的“阅读器”来说,它是新的订单并再次创建它(在order具有相同的orderId),所以我一遍又一遍地获得相同的订单。.我必须说,有时它的速度足够快,并且该订单获得了更新..但大多数时候太慢了,并且再次创建了该订单。我还尝试放置“ Repository.ordersIdMap.put(order.orderID,order);”。就在if条件旁边..这样,无论如何,地图都将具有键..但是仍然不起作用(为什么..?dunno)..如果我不使用platform.runlater ..它可以正常工作但我得到了很多NullPointersException ..导致即时通讯试图将用户界面更新为快速..我认为..任何答案都非常有用!..谢谢!对不起我的英语。
编辑:这是整个代码.. execRpt就像一个“小订单”,因此我可以创建一个更大的订单..我收到许多execRpt,然后创建订单..如果该订单存在,则更新..如果没有添加它,但更新失败(有时),并且仅添加订单,就像它是新订单一样。
还要注意,“因为如果我要再下一个订单,而Platform.runLater尚未完成..订单未在地图上创建”,这是没有道理的:当您调用
想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
6年前关闭。
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的ordersCollection(我的tableView的源)。如果集合中已存在该订单,则无法添加订单,因此在我的地图中将orderId(字符串)保存为键,这样,如果再次出现同一订单,则必须更新它(否则代码不在此处,而是现在不重要)。问题是,调用Platform.runLater绘制到UI会给我带来问题。为什么?原因是如果我要再获得一个订单,而Platform.runLater尚未完成..则该订单未在地图上创建,因此对我的“阅读器”来说,它是新的订单并再次创建它(在order具有相同的orderId),所以我一遍又一遍地获得相同的订单。.我必须说,有时它的速度足够快,并且该订单获得了更新..但大多数时候太慢了,并且再次创建了该订单。我还尝试放置“ Repository.ordersIdMap.put(order.orderID,order);”。就在if条件旁边..这样,无论如何,地图都将具有键..但是仍然不起作用(为什么..?dunno)..如果我不使用platform.runlater ..它可以正常工作但我得到了很多NullPointersException ..导致即时通讯试图将用户界面更新为快速..我认为..任何答案都非常有用!..谢谢!对不起我的英语。
编辑:这是整个代码.. 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();
}
}
}
最佳答案
您的代码中的一个问题是您有一个非原子的“先检查后行动”模式。一种解决方法是:
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()
时,将放出可运行对象在队列中,但是异步执行(除非您的方法已经在FX Thread上运行)。10-06 10:06