-1

I have a superclass called GameThread:

public class GameThread implements Runnable {
public static Thread thread;
public static boolean running = false;
public static double fps = 1;
public static double timePerTick = 1000000000 / fps;

public static ArrayList<GameThread> gameThreads = new ArrayList<>();

public void run(){
    double delta = 0;
    long now;
    long lastTime = System.nanoTime();
    long timer = 0;

    while(running){
        now = System.nanoTime();
        delta += (now - lastTime) / timePerTick;
        timer += now - lastTime;
        lastTime = now;

        setFps();

        if(delta >= 1){
            action();
            delta--;
        }

        if(timer >= 1000000000){
            timer = 0;
        }
    }
}

public synchronized void start(){
    if (running) return;
    running = true;
    startThread();
    thread.start();
}

public void action(){}
public void setFps(){}
public void startThread(){}

And 2 threads which are children of GameThread:

public class JumpThread extends GameThread {
public JumpThread(){
    start();
}

@Override
public void action(){
    //code
}

@Override
public void setFps(){
    //code
}

@Override
public void startThread(){
    thread = new Thread(new JumpThread());
}

and

public class HydroponicsThread extends GameThread {
public HydroponicsThread(){
    start();
}

@Override
public void action(){
    //code
}

@Override
public void setFps(){
    //code
}

@Override
public void startThread(){
    thread = new Thread(new HydroponicsThread());
}

My problem is, when I initialize them:

GameThread.gameThreads.add(new HydroponicsThread());
GameThread.gameThreads.add(new JumpThread());

Only the first one (HydroponicsThread) works, the "run()" method on the other won't be called. My guess is the while loop is stopping the JumpThread from being initialized, but I can't find a way to do this without it. Thanks in advance.

Tom
  • 125
  • 10
  • Your code starts no threads and fails with a `StackOverflowError`. `JumpThread` constructor -> `start()` -> `startThread()` -> `JumpThread` constructor. – Marko Topolnik Nov 27 '16 at 12:20
  • The first one works just fine. If I change their order the other one will work. – Tom Nov 27 '16 at 12:22
  • 2
    Ah yes, you prevent it with the flag. However... still quite bad code. – Marko Topolnik Nov 27 '16 at 12:24
  • I am aware its bad code. I started trying to teach myself to code a few months ago – Tom Nov 27 '16 at 12:25
  • Another obvious fail: `public static Thread thread;` You use a static variable from instance context. – Marko Topolnik Nov 27 '16 at 12:25
  • 2
    And `running` is also static, which trivially explains why only your first thread starts. It changes the flag to true once, and then it's true for all instances. If you make it non-static, then you'll get the stack overflow I mentioned above. – Marko Topolnik Nov 27 '16 at 12:29

2 Answers2

1

I found my mistake, in the start() method:

public synchronized void start(){
    if (running) return;
    running = true;
    //startThread(); (mistake)
    thread = new Thread(this);
    thread.start();
}

Also, I removed the start() method from the threads' constructor

Tom
  • 125
  • 10
0

In order to avoid "hugging" the cpu you should introduce some pause in the action of your run method, either using sleep or wait.

Check Difference between wait() and sleep() for a discussion of your options.

Community
  • 1
  • 1
p.marino
  • 6,244
  • 3
  • 25
  • 36