0

I have been making a mario game and have made good progress. Now I need to switch between worlds. First I stop the thread running my update and draw methods, then I remove everything that is in the world(player , enemies , grass , etc.) and then I load a new world. Then I try to start the thread again. But for some reason after stopping the thread, nothing is executed after that and it just 'freezes' right there.

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;
        }

    }
}
ARJAV GARG
  • 19
  • 9
  • Maybe this helps. "Once a thread stops you cannot restart it" http://stackoverflow.com/questions/1881714/how-to-start-stop-restart-a-thread-in-java – RubioRic Apr 03 '16 at 07:23
  • But it does not even print stopped ! Look at the clearWorld method – ARJAV GARG Apr 03 '16 at 07:24
  • I suspect you have a deadlock situation. Can you show us a stack dump and have a look at what the threads are doing in your debugger when this happens? – Peter Lawrey Apr 03 '16 at 07:26
  • If your main game thread is just one big loop - it will never stop, you must provide some way for main game thread - so it will know it must stop, then you can wait for it. e.g. `while (!running)` but then running must be `atomic` or `violatile` (don't know what it is exactly in Java) – csharpfolk Apr 03 '16 at 07:27
  • Note: when you call `join()` you are holding the lock so no other thread can obtain it. – Peter Lawrey Apr 03 '16 at 07:27
  • BTW if you do `while(running)` and you haven't used `volatile` or `synchronized` the value can be inlined and changing it later will have no effect. – Peter Lawrey Apr 03 '16 at 07:28
  • @ARJAVGARG Sorry, my mistake. I assume that you use thread.stop(). – RubioRic Apr 03 '16 at 07:28

1 Answers1

1

Thread.join suspends the calling thread and waits for the target thread to die. What's happening in your code is that the thread that calls clearWorld is waiting for the game thread to terminate.

EDIT: After your update I see that it's the game thread itself that is calling join. That is guaranteed to cause the call to join to block forever. See Thread join on itself for an explanation.

Since you're doing everything in one thread there's really no need for the join or start at all.

If you did have multiple threads, then a better way to do this would be to have a variable in your game thread that checks to see if the game execution is paused. Maybe something like this:

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;
    }
}

Your clearWorld and switchWorld methods can then call pause and unpause on the game thread.

Community
  • 1
  • 1
Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86