(可能)很简单 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 并且另一个线程必须调用它。