在Thread.join()

时间:2016-04-03 07:19:13

标签: java multithreading

我一直在进行马里奥比赛并且取得了很好的进步。现在我需要在世界之间切换。首先,我停止运行我的更新和绘制方法的线程,然后我删除世界上的所有东西(玩家,敌人,草等),然后我加载一个新的世界。然后我尝试再次启动线程。但是由于某种原因,在停止线程之后,在此之后没有执行任何操作,它只会冻结'就在那里。

private synchronized void clearWorld() {
    stop();
    System.out.println("Stopped");
    for(int a = 0 ; a < handler.wall.size() ; a++) handler.wall.remove(handler.wall.get(a));
    for(int b = 0 ; b < handler.creature.size() ; b++) handler.creature.remove(handler.creature.get(b));
    System.out.println("Everything  removed");
}

private synchronized void switchWorld(String path) {
    world = new World(this , path);
    start();
    System.out.println("Thread started");
}
public synchronized void stop() {
    if(!running) return ;
    running = false ;
    try {
        Main.getGame().thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
public synchronized void start() {
    if(running) return ;
    running = true ;
    Main.game.thread.start();
}

 public void run() {
    init();
    long lastTime = System.nanoTime();
    final double amountOfTicks = 60.0;
    double ns = 1000000000 / amountOfTicks;
    double delta = 0;
    int updates = 0;
    int frames = 0;
    long timer = System.currentTimeMillis();

    while(running){
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;
        if(delta >= 1){
            tick();
            updates++;
            delta--;
        }
        render();
        frames++;

        if(System.currentTimeMillis() - timer > 1000){
            if(world.Goombas==getPlayer().gKilled ) {
                clearWorld();
                switchWorld("/pipe_world1.txt");
            }
            timer += 1000;
            System.out.println(updates + " Ticks, Fps " + frames);
            updates = 0;
            frames = 0;
        }

    }
}

1 个答案:

答案 0 :(得分:1)

Thread.join挂起调用线程并等待目标线程死掉。您的代码中发生的是调用clearWorld的线程正在等待游戏线程终止。

编辑:更新后,我发现正在调用join的游戏线程本身。这保证会导致对join的调用永远阻止。有关说明,请参阅Thread join on itself

由于您在一个主题中执行所有操作,因此根本不需要joinstart

如果您确实有多个线程,那么更好的方法是在游戏线程中设置一个变量来检查游戏执行是否暂停。也许是这样的:

class GameThread extends Thread {
    private volatile boolean paused;

    public void run() {
        while (true) {
            if (!paused) {
                executeGameLogic();
            } else {
                // Put something in here so you're not in a tight loop
                // Thread.sleep(1000) would work, but in reality you want
                // to use wait and notify to make this efficient
            }
        }
    }

    public void pause() {
        paused = true;
    }

    public void unpause() {
        paused = false;
    }
}

您的clearWorldswitchWorld方法可以在游戏主题上调用pauseunpause