重温 GWT 客户端多线程
GWT client side multithreading revisited
我正在将一个 swing 应用程序转换为 GWT,它大量使用了多线程。该代码在后台运行连续的数值模拟,并以图形方式显示每一帧的结果。模拟需要知道每次计算经过了多少 real 时间。
摇摆
Thread calculate = new Thread(new Runnable(){
// run calculation cycles every 10 ms
// (or as fast as possible)
long prevT=System.currentTimeMillis();
while(!isFinished){
long currT = System.currentTimeMillis(),
dt = currT-prevT;
if(dt<10) Thread.sleep(5);
else{
simulate(dt);
prevT = currT;
}
}
}
// Update UI every 60 ms
java.awt.Timer timer = new Timer(60, new ActionListener(){public void actionPerformed(ActionEvent e){
results = getCurrentSimState();
uiPanel.render(results);
}});
此外,还有来自用户的事件驱动代码可以更改模拟器状态。
在 GWT 中实现它的最佳方法是什么?大多数以前的多线程问题主要与异步客户端-服务器工作有关。我看到了这个问题 Threading in GWT (Client),我想知道 Scheduler
是否合适:
GWT
void onLoad(){
AnimationScheduler.get().requestAnimationFrame(callback, uiElement);
}
AnimationCallback cb = new AnimationCallback(){public void execute(double t){
results = getCurrentSimState();
render(results, uiElement);
AnimationScheduler.get().requestAnimationFrame(callback, uiElement);
}};
double prevT=Duration.currentTimeMillis();
Scheduler.get().scheduleIncremental(new RepeatingCommand(){ public void execute() {
double currT = Duration.currentTimeMillis(),
dt = currT-prevT;
if(dt>30){
calculate(dt);
prevT = currT;
}
return isFinished;
}});
由于我是 GWT 的新手,我真的很想知道
- 这个设计可行吗?从线程设计到事件驱动设计是非常混乱的。
- 我不知道哪一个可能 "ticking" 更快。这两件事中哪一件优先?
RepeatingCommand
中的计算,还是AnimationScheduler
中的GUI更新?
- 这个设计有什么重要的注意事项吗?我不希望页面被锁定!我任意选择了对两个线程使用不同的调度方式——这样正确吗?如果是,为什么?
- 10 毫秒可能太快了,但是有没有办法猜测合理的计算速率是多少?模拟器更新得越快,它就越准确。 (是RK4求解的刚性偏微分方程组!)
您可能需要考虑使用 Web Worker 进行真正的后台处理,而不是 "simulating" 使用 Scheduler 的多线程。
请注意,使用调度程序中的增量命令,您必须在工作完成时 return "false",或者在需要继续时 "true"。此命令仅在您可以将计算分成小块,然后将控制权交还给 JavaScript 可以执行用户操作的块之间时才有效。
如果您不能将工作分成小块,只有在每个计算周期花费的时间少于计算间隔的时间时,使用调度程序的方法才会起作用,从而给 JavaScript 一个对用户做出反应的机会activity计算之间。
我正在将一个 swing 应用程序转换为 GWT,它大量使用了多线程。该代码在后台运行连续的数值模拟,并以图形方式显示每一帧的结果。模拟需要知道每次计算经过了多少 real 时间。
摇摆
Thread calculate = new Thread(new Runnable(){
// run calculation cycles every 10 ms
// (or as fast as possible)
long prevT=System.currentTimeMillis();
while(!isFinished){
long currT = System.currentTimeMillis(),
dt = currT-prevT;
if(dt<10) Thread.sleep(5);
else{
simulate(dt);
prevT = currT;
}
}
}
// Update UI every 60 ms
java.awt.Timer timer = new Timer(60, new ActionListener(){public void actionPerformed(ActionEvent e){
results = getCurrentSimState();
uiPanel.render(results);
}});
此外,还有来自用户的事件驱动代码可以更改模拟器状态。
在 GWT 中实现它的最佳方法是什么?大多数以前的多线程问题主要与异步客户端-服务器工作有关。我看到了这个问题 Threading in GWT (Client),我想知道 Scheduler
是否合适:
GWT
void onLoad(){
AnimationScheduler.get().requestAnimationFrame(callback, uiElement);
}
AnimationCallback cb = new AnimationCallback(){public void execute(double t){
results = getCurrentSimState();
render(results, uiElement);
AnimationScheduler.get().requestAnimationFrame(callback, uiElement);
}};
double prevT=Duration.currentTimeMillis();
Scheduler.get().scheduleIncremental(new RepeatingCommand(){ public void execute() {
double currT = Duration.currentTimeMillis(),
dt = currT-prevT;
if(dt>30){
calculate(dt);
prevT = currT;
}
return isFinished;
}});
由于我是 GWT 的新手,我真的很想知道
- 这个设计可行吗?从线程设计到事件驱动设计是非常混乱的。
- 我不知道哪一个可能 "ticking" 更快。这两件事中哪一件优先?
RepeatingCommand
中的计算,还是AnimationScheduler
中的GUI更新? - 这个设计有什么重要的注意事项吗?我不希望页面被锁定!我任意选择了对两个线程使用不同的调度方式——这样正确吗?如果是,为什么?
- 10 毫秒可能太快了,但是有没有办法猜测合理的计算速率是多少?模拟器更新得越快,它就越准确。 (是RK4求解的刚性偏微分方程组!)
您可能需要考虑使用 Web Worker 进行真正的后台处理,而不是 "simulating" 使用 Scheduler 的多线程。
请注意,使用调度程序中的增量命令,您必须在工作完成时 return "false",或者在需要继续时 "true"。此命令仅在您可以将计算分成小块,然后将控制权交还给 JavaScript 可以执行用户操作的块之间时才有效。
如果您不能将工作分成小块,只有在每个计算周期花费的时间少于计算间隔的时间时,使用调度程序的方法才会起作用,从而给 JavaScript 一个对用户做出反应的机会activity计算之间。