Skip to main content
gamedev.net
🔒 Locked 🎮 Unity

[java] Little Thread help w/ code

Started by Cakey Feb 11, 2009 at 8:53 PM 7 replies 1.4k views
Original Post
Cakey
Cakey
This is my first time actually doing threading. So here's what I want, I want to make a thread that simply just waits X miliseconds, then returns true after it has. Here's the code for the thread class that I have so far.


public class TimerThreading implements Runnable{
	private Thread timerThread;
	private long pause = 0;
	private boolean timesUp = false;
	
	public TimerThreading(String threadName, long pauseLength){
		timerThread = new Thread(this, threadName);
		pause = pauseLength;
		System.out.println(timerThread.getName());
		timerThread.start();
	}
	
	public void run() {
		try{
			timerThread.sleep(pause);
			timesUp = true;
		}catch(InterruptedException e){timesUp = false;}
	}
	
	public boolean goodToGo(){return timesUp;}
}
Here's the code I have calling it inside of a display method in a different class:

if(tTimer.goodToGo()){
	System.out.print "Timer rings!";
}
it's just not working...I'm perdy clueless so if anyones got a good link or some pointers it'd be appreciated!
kodeninja
kodeninja
I'm not entirely sure what your asking, but here is my assumption:
Some Function:TimerThreading tTimer = new TimerThreading("ThreadName", 1000);if(tTimer.goodToGo()){	System.out.print "Timer rings!";}


If that is the case, then the reason that goodToGo is never returning "true" is because when the function is called timesUp is still false. What you need is to cause goodToGo to block the calling thread until the state of timesUp changes.

I haven't touched threading in java for a while, but I believe there are two options, either use the synchronized keyword which would look like this:
public class TimerThreading implements Runnable{	private Thread timerThread;	private long pause = 0;	private boolean timesUp = false;		public TimerThreading(String threadName, long pauseLength){		timerThread = new Thread(this, threadName);		pause = pauseLength;		System.out.println(timerThread.getName());		timerThread.start();	}		public synchronized void run() {		try{			timerThread.sleep(pause);			timesUp = true;		}catch(InterruptedException e){timesUp = false;}	}		public synchronized boolean goodToGo(){return timesUp;}}


Though it feels a bit hackish to me, it should work. The "proper" way might be to use the wait/notify/notifyAll functions that are provided with every object created in java. There are many tutorials that are written on that subject here, and since I'm a bit hazy myself, I won't go into it. :P

Ps. I didn't actually test the code, but that's how I remember it working. :)
Cakey
Cakey
oyyy, thanks for the info(code didn't run). I've been looking everywhere and I'm beginning to wonder if maybe my approach is wrong...

Let me try to make it more clear, I think you understood but maybe to another passer-by.

I have a Thread class and a Game class.
I want my Thread class to be instantiated in my Game class.
Then durring the iterations of the Display method in my game class, for every X seconds/miliseconds(thread) a boolean value to be set to true, otherwise, false.

[side-bar]From messing with the code though I had a funny thing happen hahaha, my game would only render every x seconds.


kodeninja
kodeninja
Ah, I see a bit better now. Yeah the code I provided should of made goodToGo() block (wait) until run was all done being called, which would of explained why your render loop would of done that.

So by my current understanding you simply want timesUp to toggle back and forth between true and false?
ie. on for 10 ms, off for 10 ms, on for 10 ms, etc. ?

Going by that assumption, you need a loop of some sort inside your run method. When the thread starts, it calls the run method once. Once the method is completed, the thread done (and I believe, can't be restarted, thought you are free to create a new thread object pointing at your runnable class)

Again, going by my assumption (and using your original code), you might want to replace your run method with something like:
	public void run() {		// Keep looping until the thread is stopped		// You could also replace this with a variable or a test		// that would abort the loop, and finish the thread		while (true)		{			try {				// Wait a certain amount of time				timerThread.sleep(pause);				// Toggle TimesUp				timesUp = !timesUp;			}catch(InterruptedException e){}		}	}


That would wait for x amount of time, change the boolean to the opposite value (false => true, true => false), then wait x amount of time again, and change it back.

Anyway, hopefully I've hit closer this time. :)
Cakey
Cakey
Hmmm. I like this one a lot more. Thanks a bunch for taking interest in my problem.
Glass_Knife
Glass_Knife
The problem here is that threads do not return anything. The reason your first example doesn't work is because you have no idea when the thread code will run.

Do you even need a thread?

When you call this, it will return false most of the time because you are waiting in the thread. However, if you set the wait to 0, and run this a bunch of times, I think you will find that sometimes it returns true, and sometimes it returns false.

if(tTimer.goodToGo()){

System.out.print "Timer rings!";

}
Cakey
Cakey
Here's the working code that I have right now.

//This goes above all methodsprivate TimerThreading NPCtimer = new TimerThreading("NPCTimer", 500L);


	//This goes in the display method	if(NPCtimer.goodToGo()) {		//Do NPC AI		//...		//Create new timer thread to re-run		NPCtimer = new TimerThreading("NPCtimer", 500l);	}


TimerThread class.
public class TimerThreading implements Runnable{	private Thread timerThread;	private long pause = 0l;	private boolean timesUp = false;		public TimerThreading(String threadName, long pauseLength){		timerThread = new Thread(this, threadName);		pause = pauseLength;		timerThread.start();	}	public void run() {		while (timesUp == false){			try {				timesUp = false;				Thread.sleep(pause);				timesUp = true;			}catch(InterruptedException e){}		}	}	public void reset(){timesUp = false;}	public boolean goodToGo(){return timesUp;}}


Essentially I don't need a thread, and could just time this by the FPS, howeve I'd like to avoid counter variables at all costs. Thanks for all the input!
Angex
Angex
This is an example of a class I use for simple timeouts in a single thread.

package timeout;public class Timeout {	// Time this timeout started.	private long start;	// Time to wait before this timeout has finished.	private long delay;	// May want to add more complex behaviour.	// Could allow pause() / resume() functionality.	private boolean hasElapsed;	// May want to add more complex behaviour.	// Could allow pause() / resume() functionality.	private boolean isRunning;	public Timeout() {		setDelay(0L);		stop();	}	public Timeout(final long delay) {		reset(delay);	}	private void setElapsed(final boolean hasElapsed) {		this.hasElapsed = hasElapsed;	}	private void setRunning(final boolean isRunning) {		this.isRunning = isRunning;	}	private void setDelay(final long delay) {		this.delay = delay;	}	public void reset(final long delay) {		stop();		if (delay >= 0L) {			start = getCurrentTime();				setDelay(delay);			setRunning(true);		}	}	// NB: For client code:	// "while (t.isRunning());" is NOT equivalent to "while (!t.hasElapsed());"	// TODO: Change name; it is mis-leading.	public boolean isRunning() {		return isRunning;	}	public boolean hasElapsed() {		if (isRunning()) {			update();		}		return hasElapsed;	}	private void update() {		final long current = getCurrentTime();		final long diff = (current - start);		if (diff >= delay) {			// NB: Don't use stop().			notifyTimeoutFinished();		}	}	private void notifyTimeoutFinished() {		setRunning(false);		setElapsed(true);	}	// Request timeout to halt; therefore it cannot have elapsed.	public void stop() {		setRunning(false);		setElapsed(false);	}	public static long getCurrentTime() {		// May want to add more complex behaviour.		// Possibly fix current time for each frame processed.		return System.currentTimeMillis();	}}


It can be used like this:

private Timeout npcTimer = new Timeout();//...if (npcTimeout.hasElapsed() || (!npcTimeout.isRunning()) {    // Do NPC AI.    npcTimeout.reset(500L);}


However if eventually the aim is to have the AI execute in it's own thread; have you considered something like Timer and TimerTask classes.

Just be aware each task of a Timer executes in sequence NOT parallel.
Cakey
Cakey
Wow, that's a sexy little class!

See my game's "AI" is verrrry basic. It's for a 2-D RPG similar to Earthbound so basically all I need my NPC's to do is meander around and not collide with things etc(already done with that).

Here's a video I took using a screen capture tool, of it in action.



If you take the time to watch my little clip(30 seconds or so long), please do throw out some input, or comments :). I'm not trying to spam, but I guess this could be used as an example on what you can do with the code that has been provided.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.