My GUI has a button (start/stop) that can either START (spawn Thread/Runnable) or STOP (stop Thread/Runnable).
The way I implemented stop (as per all the feedback) was using a boolean. So my thread/runnable has a WHILE(run==true) and the .STOP method changes the boolean run==false.
This seems to work great, I put a Timeout on my thread (10seconds) so the loop is forced to run every 10seconds (incase it gets stuck and I want to stop it) - FYI: the thread/runnable has a DataSocket.recieve (that is what the Timeout is for, incase the thread/runnable is waiting for a response and I still want to stop it so I force a SocketException: Recieve Time out (BTW: is it bad to have these? I put the timeout to 10seconds so I get a lot of exception [not that many recieves when testing], is this Bad practice?)
Anyways, back to the real question. My current problem is this scenario:
- User presses start - Thread/Runnable launches - everyone chats, all is good, all is happy - User presses Stop - Immediatly after user presses Start again ERROR....(thread exception)
The Error is because the Thread I stopped had not actually stopped yet (needs 10 seconds) but the user tries to Start it again anyways.. So I need a way to DISABLE the START button until I am sure the thread has stopped...
I tried something like this: // Stop Server sMain.stop(); // This is my Thread/Runnable startStop.setEnabled(false); // Disable button so user cannnot click while (sMain != null){} // It seems this doesn't work.... startStop.setEnabled(true); // Enable button to allow start again startStop.setLabel("START");
All this did was use 100% CPU until I end-tasked. How can I accomplish this task?
[Pseudo-Code] --THREAD/RUNNABLE serverMain (sMain) -- while (run==true) { // Do all the work }
public void stop() { run = false; // so the next time the while loop runs it will exit then the thread will finish and should become NULL no? } [Pseudo-Code]
One problem remains: You probably will wait for the Thread to wait like that:
while(myClassInstance.getThreadInactive());
That causes a massive processor usage. The solution is to put everything the Thread is doing in a synchronized method and also make getThreadInactive a synchronized method. This way your main program will only continue when the doSomething method is finished.
class MyClass extends Runnable () {
boolean runThread = true;
boolean threadStopped = true;
publicvoid run() {
while (runThread) {
threadStopped = false;
doSomething(); //while this method is active, any other synchronized method can be called, but won't be executed until this one ends.
}
threadStopped = true;
}
privatesynchronizedvoid doSomething() {
//...do Something
}
publicvoid stop() {
runThread = false;
}
publicsynchronizedboolean getThreadInactive() //waits for doSomething() to stop
return threadStopped;
}
publicboolean getThreadInactiveRealTime() {
return threadStopped;
}
}
One more thing: If you post code, please use the java tags as shown on the right side of the input window. That makes the code easier to read.