我正在制作一个平台游戏,让玩家每隔30毫秒跳过一次,向上增加一点力量。我以为我会使用多线程,因为我之前做过一点点,看起来很简单。无论如何,我试过这个:
public void jump() {
new Runnable() {
public void run() {
for (int i = 0; i <= jumpForce; i++) {
velocity.y++;
System.out.println("Adding force");
try {
wait(30);
} catch (InterruptedException e) {}
}
}
}.run();
}
现在,我想到的这将是从0到jumpForce的每个循环(在这种情况下为50),它在y速度变量上加1然后等待30ms,但实际发生的是我得到一个错误:
java.lang.IllegalMonitorStateException
我不知道这意味着什么,所以有人能告诉我我做错了什么?
答案 0 :(得分:1)
javadoc对wait
说:
此方法只应由作为其所有者的线程调用 这个对象的监视器。有关的说明,请参阅notify方法 线程可以成为监视器所有者的方式。
您拥有一个带有同步块的监视器,将您的代码更改为:
synchronized (this) {
wait(30);
}
答案 1 :(得分:1)
如果要在不同的线程中执行此代码,则应 NOT 调用Runnable的run()
方法。你应该做的是创建一个线程的实例,并将你的Runnable实现放在它的构造函数中。
然后调用.start()
。
public void jump() {
new Thread(new Runnable() {
public void run() {
for (int i = 0; i <= jumpForce; i++) {
velocity.y++;
System.out.println("Adding force");
try {
Thread.sleep(30);
} catch (InterruptedException e) {}
}
}
}).start();
}
在这种情况下你应该sleep()
线程而不是wait()
,因为你没有采用对象锁定。为了使用wait()实现所需,方法jump()
必须是synchronized
,另一个线程必须调用它。
答案 2 :(得分:0)
您不是多线程的,因为您没有创建任何线程
Runnable正在运行它的同一个线程中运行。如果您要创建新主题,则必须使用new Thread(new Runnable())
明确执行此操作并使用Thread#start()
。
无论如何,您可能只想安排一项任务,以便更好地使用ScheduledExecutorService:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
// do something
}
}, 0, 30, TimeUnit.SECONDS);