(可能)相当简单的Java多线程问题

时间:2016-02-15 22:21:22

标签: java multithreading runtime-error

我正在制作一个平台游戏,让玩家每隔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

我不知道这意味着什么,所以有人能告诉我我做错了什么?

3 个答案:

答案 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);