Phi*_*987 9 java multithreading z80 timing
我有一个奇怪的问题 - 我希望有人可以向我解释发生了什么,以及可能的解决方法.我在Java中实现了一个Z80核心,并试图通过在一个单独的线程中使用java.util.Timer对象来减慢它的速度.
基本设置是我有一个线程运行一个执行循环,每秒50次.在此执行循环中,执行许多循环,然后调用wait().外部Timer线程将每隔20ms调用Z80对象上的notifyAll(),模拟PAL Sega主系统时钟频率为3.54 MHz(ish).
我上面描述的方法在Windows 7(试过两台机器)上工作得很好,但我也试过两台Windows XP机器,而且在这两台机器上,Timer对象似乎睡过了大约50%左右.这意味着在Windows XP计算机上,一秒钟的仿真时间实际上大约需要1.5秒左右.
我尝试使用Thread.sleep()而不是Timer对象,但这具有完全相同的效果.我意识到大多数操作系统的时间粒度不会超过1毫秒,但我可以忍受999毫秒或1001毫秒而不是1000毫秒.我不能忍受的是1562ms - 我只是不明白为什么我的方法在较新版本的Windows上运行正常,但不是旧版本 - 我调查了中断期等等,但似乎没有已经开发出一种解决方法.
有谁能告诉我这个问题的原因和建议的解决方法?非常感谢.
更新:这是我为了显示相同问题而构建的较小应用的完整代码:
import java.util.Timer;
import java.util.TimerTask;
public class WorkThread extends Thread
{
private Timer timerThread;
private WakeUpTask timerTask;
public WorkThread()
{
timerThread = new Timer();
timerTask = new WakeUpTask(this);
}
public void run()
{
timerThread.schedule(timerTask, 0, 20);
while (true)
{
long startTime = System.nanoTime();
for (int i = 0; i < 50; i++)
{
int a = 1 + 1;
goToSleep();
}
long timeTaken = (System.nanoTime() - startTime) / 1000000;
System.out.println("Time taken this loop: " + timeTaken + " milliseconds");
}
}
synchronized public void goToSleep()
{
try
{
wait();
}
catch (InterruptedException e)
{
System.exit(0);
}
}
synchronized public void wakeUp()
{
notifyAll();
}
private class WakeUpTask extends TimerTask
{
private WorkThread w;
public WakeUpTask(WorkThread t)
{
w = t;
}
public void run()
{
w.wakeUp();
}
}
}
Run Code Online (Sandbox Code Playgroud)
所有主类都创建并启动其中一个工作线程.在Windows 7上,此代码产生的时间约为999毫秒 - 1000毫秒,这完全没问题.然而,在Windows XP上运行相同的jar会产生大约1562ms到1566ms的时间,这是在我测试过的两台独立的XP机器上.它们都运行Java 6更新27.
我发现这个问题正在发生,因为Timer正在休眠20ms(相当小的值) - 如果我将所有执行循环一秒钟塞进等待wait() - notifyAll()循环,这会产生正确的结果 - 我确定那些看到我正在尝试做的事情(以50fps模拟Sega Master System)的人会看到这不是一个解决方案 - 它不会给出交互式响应时间,每50个跳过49个.正如我所说,Win7应对此问题.对不起,如果我的代码太大:-(
| 归档时间: |
|
| 查看次数: |
1571 次 |
| 最近记录: |