1
\$\begingroup\$

I'm having a really hard time understanding Threads and their contents.

What I'd like to have is a main game object (which I have) and a loop, where I can measure the time it takes for two threads to finish doing their work.

So far I have two threads running like so, which are likely a poor idea:

public void run(){
    while(true){
         // do stuff, like update logics and draw to screen, in separate threads
    }
}

With which I get times measured from both threads, how long an iteration takes. But, I can't seem to figure out how to get the times measured, combine them to get a total time of time spent per iteration.

After some modifications, I have, which seems to work, but I notice a drop in FPS, surely there's a better way?

    public void Loop(){
        while(this.on){
            long time = System.nanoTime();
            this.updater = new Thread(this.canvas.logic);
            this.updater.start();
            this.drawer = new Thread(this.canvas);
            this.drawer.start();
            try{
                this.updater.join();
                this.drawer.join();
            }catch(InterruptedException e){

            }
            this.elapsed = (System.nanoTime() - time) * 0.0000001;
            System.out.println(this.elapsed);   
        }
    }

I'll gladly provide more information as asked.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You probably don't want to run the update and rendering phases as two parallel threads, since rendering depends on object state data that's being changed in update. If you use double buffering so you're updating the next frame's data while rendering the previous frame, you add latency where what's on screen is always a snapshot from one update in the past. In this answer, I talk about how threads are more commonly used to "go wide" to spread the work of each processing phase across multiple cores, rather than giving each phase its own thread. \$\endgroup\$
    – DMGregory
    Commented Apr 20 at 13:05

2 Answers 2

0
\$\begingroup\$

My "game loop" uses a timer object that fires and runs a block of code every 50 ms. In that 50 ms, I run everything I need to do: move objects, etc. So, effectively running at 20 FPS which is adequate for my needs.

For timing the actual work, I start the performance counter at the start of the interval, and measure when the work is done for that interval. That elapsed time can be compared to the (timer) "interval time", and tells you what % of the time you're actually doing "work", and how many more FPS you might expect.

I'm transitionimg to multiple independent animations; in this case, the "Game loop" will include one or more "monitor loops" (additional timer threads), to oversee; and which could run at different intervals depending on what they're monitoring (traveling vs firing vs fighting "loops").

\$\endgroup\$
0
\$\begingroup\$

Using threads directly is bad idea. You are always creating new threads instead of reusing them. Running new threads and switching between your updater, drawer and loop threads takes lot of time. Instead you can use executor to run your jobs for you. Here is a bit customized code I tested:

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
//....
private void loop2() throws ExecutionException {
    ExecutorService es = Executors.newFixedThreadPool(2);
    while(this.on) {
        long time = System.nanoTime();
        Future<?> updater = es.submit(canvasLogic);
        Future<?> drawer = es.submit(canvas);
        try{
            updater.get();
            drawer.get();
        }catch(InterruptedException e){

        }
        double elapsed = (System.nanoTime() - time) * 0.0000001;
        System.out.println(elapsed);
    }
}

In my quick test this improved rates tenfold

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .