【发布时间】:2011-01-22 22:25:59
【问题描述】:
我正在处理一个更复杂的版本(车辆在 X 和 Y 方向上移动)
我制作这个例子是为了获得更好的方法来实现这一点。
- 我有一辆车在 X 方向上以一定速度 (24.5872 mps) 行驶
- 我通过使用执行器每 100 毫秒增加 X 值来模拟这一点(以保持其 X 位置更准确和实时)
- 每一秒后,我都会向另一个进程发送一条消息,其中包含我刚刚覆盖的行的 xMin 和 xMax 值
- 如果前一个 X 区域中存在“坑洞”(消息回调消息到linkedblockingqueue),其他进程将响应一条 JMS 消息(通常是立即)告诉我停止。
我遇到的问题是“通常立即”部分。如果我没有足够快地得到响应,我认为它会影响我算法的整个时间。有什么更好的方法来处理这种情况?
这是我正在尝试做的一些基本代码:
public class Mover implements MessageHandler {
private static final long CAR_UPDATE_RATE_IN_MS = 100;
private static double currX = 0;
private static double CONSTANT_SPEED_IN_MPS = 24.5872; // 55 mph
private static double increment = CONSTANT_SPEED_IN_MPS / (1000 / CAR_UPDATE_RATE_IN_MS);
static LinkedBlockingQueue<BaseMessage> messageQueue = new LinkedBlockingQueue<BaseMessage>(); // ms
private static int incrementor = 0;
public static void main(String[] args) {
startMoverExecutor();
}
private static void startMoverExecutor() {
ScheduledExecutorService mover = Executors.newSingleThreadScheduledExecutor();
mover.scheduleAtFixedRate((new Runnable() {
@Override
public void run() {
currX = incrementor * increment;
if (incrementor % (1000 / CAR_UPDATE_RATE_IN_MS) == 0) {
System.out.println(currX);
sendMessage(currX - CONSTANT_SPEED_IN_MPS, currX);
// do something
try {
messageQueue.poll(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
incrementor++;
}
}), 0, CAR_UPDATE_RATE_IN_MS, TimeUnit.MILLISECONDS);
}
@Override
public void handleMessage(BaseMessage msg) {
messageQueue.add(msg);
}
protected static void sendMessage(double firstX, double secondX) {
// sendMessage here
}
}
【问题讨论】:
-
您使用 JMS 消息有什么原因吗?
-
这是您代码中的一个小加速:将
currX = incrementor * increment;更改为currX += increment;并将初始化 currX 设置为currX = -increment;只需将 * 更改为 +,就可以了。 -
@Justin 我怀疑任何想象中的加速如果它在做 IPC 是可以衡量的。重复添加也会导致更大的错误累积。
-
两件事:在您的模拟中一致性有多重要?即,每次运行在相同的地方都有坑洼很重要,还是你能接受你的车有时会随机“停止”,即使它的轨迹上没有坑洼?此外,您体验延迟的频率如何?或者您是否试图过早地优化一些在完成后会运行得足够快的东西?
-
我查看了上面的算法(不是您的代码)。为了实现这个“通常立即”的部分,我完全改变了算法(见下面我的解决方案)。