Hi. I am working on a multi threaded program (game renderer). What I want to do is to loop through my threads and get a boolean value that tells me if the thread is done rendering or not. If all the threads is done, I want the code to go on, otherwise wait. I thought I had this locked down, but it does not work. The threads work, I have checked this with sysout and such. The issue is my method of looping through them I suspect.

//this is in the draw loop of the main drawer:
    	while(stillDrawing){
    		
//My idea is to set the state of the while loop to "continue", or "done", and change this
// this if it turns out if one or more of the threads is not done.

    		stillDrawing = false;

//looping through my list of threads
    		for (DrawerThread thread : threads) {
    			
//setting the while loop to True if the thread is not waiting, iow. is running
			if(!thread.isWaiting())
    			{
    				stillDrawing = true;
    			}
		}
    		

//simply wait a little if we find that not all threads is done
if(stillDrawing){
    		try {
			this.wait(1);
		} catch (InterruptedException e) {
				e.printStackTrace();
			}
	}
}
    	

//Sysout the threads, and their states. The states are not changed until the a render method is called.
    	for (DrawerThread thread : threads) {
    		System.out.println("Thread "+thread.getId()+" is waiting: "+thread.isWaiting()+" in frame loop nr: "+loop);			
		}

Am I doing the basic logics wrong, if so, how to make this work? My rendering logics is dependent on these threads being done before the code continues. Here is a little of the console when it renders:
"
Thread 0 is waiting: false in frame loop nr: 87
Thread 1 is waiting: false in frame loop nr: 87
Thread 2 is waiting: true in frame loop nr: 87
Thread 3 is waiting: false in frame loop nr: 87
Thread 0 is waiting: false in frame loop nr: 88
Thread 1 is waiting: false in frame loop nr: 88
Thread 2 is waiting: false in frame loop nr: 88
Thread 3 is waiting: true in frame loop nr: 88
Thread 0 is waiting: false in frame loop nr: 89
Thread 1 is waiting: false in frame loop nr: 89
Thread 2 is waiting: false in frame loop nr: 89
Thread 3 is waiting: false in frame loop nr: 89
"

As we can see. Most of the threads is not actually done. I have double checked that I do not start the rendering again before this step is done (also, it is synchronized). It is also only the start rendering sequence that will set the waiting status to false, so the value is not ever changed to anything else than true when this check is running.

Thanks for the help:)

Recommended Answers

All 3 Replies

how to make this work

I think we'll need a fully working program to solve this.

Can you make a small program that executes and demos the problem?

Will work on one:)

Ok. I got the working version done now. But i got it fully working too. Turns out i left out a single boolean change that made the whole loop not working properly after the first loop. Anyways, here is the code if you want to try it out. You need to split this up into two different files.

//First file, draw.java:

import java.util.ArrayList;



public class draw{
	
	ArrayList<DrawThread> threads = new ArrayList<DrawThread>();
	
	boolean acting = false;
	boolean stillActing = false;
	long loop = 0;
public void Initialize(int numThreads) {
	
	for(int i = 0; i<numThreads; i++){
		this.threads.add(new DrawThread());
		this.threads.get(i).start();
	}
	
	this.startRun();
}

private void startRun() {
	
	while(true){
		
		startActing();
		
		
	}
	
}


private synchronized void startActing() {
	
	
	
	for (DrawThread thread : threads) {
		if(thread.isWaiting()&&!acting){
	
				thread.actAgain();		
			}
		}
	acting = true;

	
	
	while(stillActing){
		
		stillActing = false;

		for (DrawThread thread : threads) {
			if(!thread.isWaiting())
			{
				stillActing = true;
			}
		}
		
		if(stillActing){
		try {
			this.wait(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	}
	
//The line below is the thing that fixes the issue. Try with and without it if you want to see the issue I had:	
	stillActing = true; 
	acting = false;
	for (DrawThread thread : threads) {
		System.out.println("Thread "+thread.getId()+" is waiting: "+thread.isWaiting()+" in frame loop nr: "+loop);			
	}
	
	
	
	loop++;
	
}

public static void main(String[] args){
	draw dr = new draw();
	
	//input number of threads here
	dr.Initialize(4);
}

}

//Second file, DrawThread.java




public class DrawThread extends Thread{
	
	boolean waiting = false;
	static int id = 0;
	int myId;
	
	public DrawThread(){
		myId = id++;
	}
	
	public void run(){

		while (true) {
			if (!waiting) {
				act();
			} 
			else {
				synchronized (this) {
					try {
						wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	
	
	private void act() {

//something
		waiting = true;
		
	}
	
	public synchronized void actAgain() {
		
		waiting = false;
		this.notify();
		
	}
	
	public boolean isWaiting(){
		return waiting;
	}
	
	public long getId(){
		return myId;
	}
}

So. Basically this thread is resolved.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.