(可能)很简单 Java 多线程问题
(probably) Quite simple Java multi-threading issue
我正在制作一个平台游戏,让玩家每 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),它将 1 加到 y 速度变量上,然后等待 30 毫秒,但是实际发生的是我收到一个名为:
的错误
java.lang.IllegalMonitorStateException
我不知道这意味着什么所以有人可以告诉我我做错了什么吗?
javadoc 说 wait
:
This method should only be called by a thread that is the owner of
this object's monitor. See the notify method for a description of the
ways in which a thread can become the owner of a monitor.
您拥有一个带有同步块的监视器,将您的代码更改为:
synchronized (this) {
wait(30);
}
您不是多线程,因为您没有创建任何线程。
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);
如果你想在不同的线程中执行这段代码,你应该不调用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
并且另一个线程必须调用它。
我正在制作一个平台游戏,让玩家每 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),它将 1 加到 y 速度变量上,然后等待 30 毫秒,但是实际发生的是我收到一个名为:
的错误java.lang.IllegalMonitorStateException
我不知道这意味着什么所以有人可以告诉我我做错了什么吗?
javadoc 说 wait
:
This method should only be called by a thread that is the owner of this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.
您拥有一个带有同步块的监视器,将您的代码更改为:
synchronized (this) {
wait(30);
}
您不是多线程,因为您没有创建任何线程。
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);
如果你想在不同的线程中执行这段代码,你应该不调用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
并且另一个线程必须调用它。