Thread is not Stopping/Interrupting - java

I have this code sample
public static class BlinkMe extends Thread {
int counter = 0;
protected boolean stop = true;
public void run() {
while (stop) {
counter++;
if (counter % 2 == 0) {
jLabel4.setVisible(true);
jLabel7.setVisible(true);
jLabel8.setVisible(true);
counter = 0;
} else {
jLabel4.setVisible(false);
jLabel7.setVisible(false);
jLabel8.setVisible(false);
if (jButton4.isEnabled() == false) {
stop = false;
jLabel4.setVisible(true);
jLabel7.setVisible(true);
jLabel8.setVisible(true);
if (jButton2.isEnabled() == false) {
stop = true;
jButton2.setEnabled(false);
}
}
}
}
}
}
I need to stop this Thread when I press my Stop Button...
Here's the code I'm using for the Button's function but it is not working. ***The Thread is not working at ll*
Here is the Button's function
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
BlinkMe b=new BlinkMe();
b.stop(); //here I have even used b.interrupt(); but doesn't stop the
}

There are many, many things wrong in this code.
you're accessing Swing components from a background thread. That's forbidden. Only the event dispatch thread is allowed to access Swing components
You're trying to stop() a thread, although this method is deprecaed and should never, ever be used, as the documentation explains
Instead of stopping the actual thread, you create a new instance of that thread class, and call stop() on that new instance.
You "blink" without any delay between the blink.
Your thread uses a stop variable, but this variable is never modified anywhere. Even if it was, it's not volatile, so you have a big chance of not seeing the modification, and thus not stopping the thread.
Read the Swing tutorial abount concurrency. And use a Swing Timer, which is designed to do that kind of thing, safely.

You are creating a new thread in actionPerformed and trying to stop the same, which was not started so far. Try calling stop in actual thread.

The initial value of your stop is "true". This means that when the thread starts, the run method executes but will not execute the while block because the condition will result to false right away.
First, you need to change your while loop into like this:
while(!stop) { /* the rest of your code */ }
Next, you need to create a method in your BlinkMe thread that would allow other objects in your program that would make it stop. The method would look something like this:
public void stopBlinking() {
stop = true;
}
Calling the above method will stop the infinite loop in the run method.
I don't think you will see a blinking effect when you run your program. It is because the loop executes very fast. I suggest you put a Thread.sleep(1000) somewhere in the loop so that there is time to reflect the blink effect visually.

Related

How to use a 'wait' command inside any loop?

Learning Android development.
Code has to wait for few seconds/minutes/hours before going to the next statement in a for Loop.
for( i=0; i<number; i++) {
// Do Something
// Then Wait for x hours, y minutes, and z seconds. Then proceed to next command.
// Do some more things.
} //End for loop.
I searched for this but found many answers like thread.Sleep, Sleep, try{wait(); } Catch{ }, etc...
Also, found out about Handler. Can I use a Handler inside a for loop??
Rather, is there a simple command like wait(x hours, x minutes, x seconds); something like this??
Please help!!
It depends on where do you have the loop. If you run the loop in main thread, you can't "simply insert a delay" into it, because it will block execution, and Java doesn't have anything like C#'s async&await to "easily" solve this. So, the easiest way to do this is: first, move the entire loop to a background thread. Then, you can just use Thread.sleep(…) where you need a delay. But then, if you need to update UI, you can't do this directly from background thread, you will need to use a Handler, call post(Runnable) method (the passed Runnable will run on main thread), and inside that Runnable you must check if the UI is still alive (because user could "close" the application, so your Activity/Fragment/View/whatever can be finished or be in a "bad" state)
In Android there is a class that can do all what you are saying, AsyncTask.
private class YourTaskClassName extends AsyncTask<Void, Integer, Long> {
protected Long doInBackground(Void.. values) {
//Here is where you do the loop
for (int i = 0; i < number; i++) {
...
publishProgress(yourProgress); //Value passed to onProgressUpdate
}
return totalSize; //Value for onPostExecute
}
protected void onProgressUpdate(Integer... progress) {
//Here is what you wanna show while your loop is running in background
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
//Here is what you wanna do when your loop has finished
}
}
You can call it like this new YourTaskClassName().execute();
Thread.sleep(time_in_miliseconds)
looks like the simplest solution. It's a static method, so you need no instances of Thread class.
Wait is a monitor method which means you can call the method from synchronized block or method.
Use sleep for your case.
I've done Android programming in the past but not recently though. I have done lots of Java though and think that I will still be of help.
With respect to the Handler, it appears that you would be able to do this. Having looked at the documentation, http://developer.android.com/reference/android/os/Handler.html#handleMessage(android.os.Message), essentially you're posting messages or runnables from one thread and handling messages in a different thread. Your for-loop won't stop though since you're starting a new thread when using a handler.
When creating a handler, you need to override the handleMessage(Message msg) method if it's a message or post a runnable you're sending as this is the method that's called after a suitable time has ellapsed. To send your message at a specific time or after a delayed amount of time, you have postAtTime, postDelayed, sendMessageAtTime and sendMessageDelayed methods, whichever one is needed.
new Handler() {
public void handleMessage(Message msg) {
// Your code here.
}
}.sendMessageDelayed(yourMessage, theAmountOfTimeInMilles);
Also, after your message is handled, if you want to do any user-interface updating (in other words, changing anything graphical, such as updating a label or changing the background), you need to use the runOnUiThread method, otherwise it will throw an exception:
runOnUiThread(new Runnable() {
public void run() {
// Code including UI code here.
}
});

Stoping and starting a new thread after timer expires

this is my first post on Stackoverflow and obviously i dont have much knowlege about threads.
Its a console app and the thing is, when the main method starts,also the timer starts and my program executes,it involves getting information from keyboard and it works great.
After timer expires,lets say after 20 sec, it calls run() from RemindTask Class and shows me number of points i gather during that time.
Now after that i want to make option to start or not to start again my app,main method.
The thing is my main will still gather informations from keyboard cause its still executing and not from input from run() method which i want.
If i put System.exit(0), ofcourse i cannot start a new thread after it.
How do i get pass this,is there a way to say in my while loop "Until my timer didnt expired do this"? or something?
static class RemindTask extends TimerTask {
public void run() {
char answer;
System.out.println("Time expired! "+yourResult);
/* System.exit(0);
Thread t = new Thread();
t.start(); */
System.out.println("Do you continue? y/n");
Scanner in = new Scanner(System.in);
answer = in.nextLine().charAt(0);
if(answer=='y'){
System.out.println("Continue program");
String[] args = {};
Main.main(args);
}else
System.out.println("Stoping program");
System.exit(0); //Stops the AWT thread (and everything else)
}
}
static int yourResult;
public static void main(String[] args) {
int seconds=20;
timer = new Timer();
timer.schedule(new RemindTask(), seconds * 1000);
boolean contin = true;
while(contin == true){
//...a bunch of code...
//...Scanner in = new Scanner(System.in);..
//...a bunch of code...
}
Stopping a thread is not a trivial task. The short answer to how to stop a thread is: do not stop a thread from within another thread; instead, ask the thread to stop itself. The reason for this is that a thread has to stop in a safe place. If the thread which is stopped holds a mutex, for example, a deadlock may occur if another thread also requires this mutex.
First, probably it is better that you do not use the main method for polling the keyboard. Just create another thread to do this; this makes it easier to make a new thread doing the same thing later.
Second, what you have to do is pass a reference to the main thread's Thread object to your RemindTask thread. Java offers a method Thread.stop() to stop a thread, but it has been deprecated for the reason I gave above.
Instead, you have to ask the main thread to stop. Java offers a standard way of doing this. You call Thread.interrupt() on the Thread instance of the main thread. Then, in the main thread you regularly call the static method Thread.interrupted(). If it returns true, this means that some other thread has asked the current thread to terminate, and you can cleanly stop by returning from the run() method.
It's hard to get what the problem is without the call to the RemindTask.run() method. In the commented part of your code, inside the main method loop, you have a constructor call that is also inside the RemindTask.run(). Maybe that is part of the problem?

Using thread.sleep in a for loop

I am using eclipse if it would make any difference. I am trying to update a label 10 times at the press of a button, and I want it to wait between updates. I am trying to use thread.sleep in a for loop, but it does not update the label until the for loop reaches an end.
The code is close to. It also has much more code in it to specify what to change the label to.
for (int i = 0; i < 10; i++) {
try{
thread.sleep(250);
}catch(InterruptedException ie) {
return;
}
panel.repaint();
}
Thanks, it really helped!
For the label to be updated, the main GUI event loop has to get its turn. But I'm guessing your code is running in the main thread, so the redrawing can't occur until your code is completely finished.
What you need to do is put your sleeping loop into a separate thread.
For this task, the SwingWorker class might be useful.
Swing has a single thread (commonly called the Swing thread) and all button presses, redraws, processing, updates, etc happen in that thread.
This means that if you block that thread (such as for example by sleeping in a loop) then it cannot redraw the screen until you finish.
You need to farm out the work to another thread such as by using SwingWorker or user a Timer to schedule the updates. Swing has a Timer class you can use that is designed for exactly this case, just tell it to call you back every 250ms and make the change in that callback.
May be i am not getting your exact problem otherwise below is the solution:
for (int i = 0; i < 10; i++) {
try{
panel.repaint();
thread.sleep(250);
// Or here if you want to wait for 250ms before first update
}catch(InterruptedException ie) {
return;
}
}
Thoguh SwingWorker is better option. Move above logic to SwingWorker thread. Sample code is below:
class Task extends SwingWorker<Void, Void> {
#Override
public Void doInBackground() {
for (int i = 0; i < 10; i++) {
try{
panel.repaint();
thread.sleep(250);
// Or here if you want to wait for 250ms before first update
}catch(InterruptedException ie) {
}
}
return null;
}
/*
* Executed in event dispatching thread
*/
#Override
public void done() {
// Do something if you want at the end of all updates like turn off the wait cursor
}
}

Stopping thread Immediately

I want to stop a running thread immediately. Here is my code:
Class A :
public class A() {
public void methodA() {
For (int n=0;n<100;n++) {
//Do something recursive
}
//Another for-loop here
//A resursive method here
//Another for-loop here
finishingMethod();
}
}
Class B:
public class B() {
public void runEverything() {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
A a = new A();
a.methodA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
My problem is that i need to be able to stop the thread in Class B even before the thread is finished. I've tried interrupt() method, but that doesn't stop my thread. I've also heard about using shared variable as a signal to stop my thread, but I think with long recursive and for-loop in my process, shared-variable will not be effective.
Any idea ?
Thanks in advance.
Thread.interrupt will not stop your thread (unless it is in the sleep, in which case the InterruptedException will be thrown). Interrupting basically sends a message to the thread indicating it has been interrupted but it doesn't cause a thread to stop immediately.
When you have long looping operations, using a flag to check if the thread has been cancelled is a standard approach. Your methodA can be modified to add that flag, so something like:
// this is a new instance variable in `A`
private volatile boolean cancelled = false;
// this is part of your methodA
for (int n=0;n<100;n++) {
if ( cancelled ) {
return; // or handle this however you want
}
}
// each of your other loops should work the same way
Then a cancel method can be added to set that flag
public void cancel() {
cancelled = true;
}
Then if someone calls runEverything on B, B can then just call cancel on A (you will have to extract the A variable so B has a reference to it even after runEverything is called.
I think you should persevere with using Thread.interrupt(). But what you need to do to make it work is to change the methodA code to do something like this:
public void methodA() throws InterruptedException {
for (int n=0; n < 100; n++) {
if (Thread.interrupted) {
throw new InterruptedException();
}
//Do something recursive
}
// and so on.
}
This is equivalent declaring and using your own "kill switch" variable, except that:
many synchronization APIs, and some I/O APIs pay attention to the interrupted state, and
a well-behaved 3rd-party library will pay attention to the interrupted state.
Now it is true that a lot of code out there mishandles InterruptedException; e.g. by squashing it. (The correct way to deal with an InterruptedException is to either to allow it to propagate, or call Thread.interrupt() to set the flag again.) However, the flip side is that that same code would not be aware of your kill switch. So you've got a problem either way.
You can check the status of the run flag as part of the looping or recursion. If there's a kill signal (i.e. run flag is set false), just return (after whatever cleanup you need to do).
There are some other possible approaches:
1) Don't stop it - signal it to stop with the Interrupted flag, set its priority to lowest possible and 'orphan' the thread and any data objects it is working on. If you need the operation that is performed by this thread again, make another one.
2) Null out, corrupt, rename, close or otherwise destroy the data it is working on to force the thread to segfault/AV or except in some other way. The thread can catch the throw and check the Interrupted flag.
No guarantees, sold as seen...
From main thread letsvsay someTask() is called and t1.interrput is being called..
t1.interrupt();
}
private static Runnable someTask(){
return ()->{
while(running){
try {
if(Thread.interrupted()){
throw new InterruptedException( );
}
// System.out.println(i + " the current thread is "+Thread.currentThread().getName());
// Thread.sleep( 2000 );
} catch (Exception e) {
System.out.println(" the thread is interrputed "+Thread.currentThread().getName());
e.printStackTrace();
break;
}
}
o/P:
java.lang.InterruptedException
at com.barcap.test.Threading.interrupt.ThreadT2Interrupt.lambda$someTask$0(ThreadT2Interrupt.java:32)
at java.lang.Thread.run(Thread.java:748)
the thread is interrputed Thread-0
Only t1.interuuption will not be enough .this need check the status of Thread.interrupted() in child thread.

Controlling thread using wait() and notify()

(Problem solved, solution below)
I have 2 classes: Equip and Command. The equip is an equipment that run commands, but I need it to be able to run only 1 command at the same time.
A command is a thread, that executes on the run() function, while Equip is a normal class that don't extend anything.
Currently I have the following setup to run the commands:
Command class:
#Override
public void run() {
boolean execute = equip.queueCommand(this);
if (!execute) {
// if this command is the only one on the queue, execute it, or wait.
esperar();
}
// executes the command.....
equip.executeNextCommand();
}
synchronized public void esperar() {
try {
this.wait();
} catch (Exception ex) {
Log.logErro(ex);
}
}
synchronized public void continue() {
this.notifyAll();
}
Equip class:
public boolean queueCommand(Command cmd) {
// commandQueue is a LinkedList
commandQueue.addLast(cmd);
return (commandQueue.size() == 1);
}
public void executeNextCommand() {
if (commandQueue.size() >= 1) {
Command cmd = commandQueue.pollFirst();
cmd.continue();
}
}
However, this is not working. Basically, the notify() isn't waking the command thread, so it'll never execute.
I searched about the wait and notify protocol, but I couldn't find anything wrong with the code. I also tried calling the wait() directly from the queueCommand() method, but then the execution of the queueCommand stopped, and it also didn't do what it was supposed to do.
Is this approach correct and I'm missing something or this is completely wrong and I should implement a Monitor class to manipulate the concurrent threads?
EDIT: I solved the problem using another completely different approach, using Executors, thanks to #Gray.
Here's the final code, it might help someone someday:
Equip class:
private ExecutorCompletionService commandQueue = new ExecutorCompletionService(Executors.newFixedThreadPool(1));
public void executeCommand(Command cmd, boolean waitCompletion) {
commandQueue.submit(cmd, null);
if (waitCompletion) {
try {
commandQueue.take();
} catch (Exception ex) {
}
}
}
In the Command class I just have a method to encapsulate the equip's execute method.
The boolean waitCompletion is used when I need the result of the command at the same time, and instead of calling a new thread to execute it, I just execute and wait, pretending that it's executing on the same thread. This question contains a good discussion on this matter: When would you call java's thread.run() instead of thread.start()?. And yes, this is a case where it's useful to call .run() instead of .start().
There are a large number of race conditions that exist in your code if Command.run() is called from multiple threads. Unless this is some sort of homework question where you have to implement the code yourself, I would highly recommend using one of the Java Executors which were added in 1.6. In this case the Executors.newSingleThreadExecutor() is what you need to limit the number of running background tasks to 1. This will allow an unlimited number of tasks to be submitted to the ExecutorService, but only one of those tasks will be executing at any one time.
If you need the thread that is submitting the tasks to block when another task is already running then you would use something like the following. This sets up a pool of a maximum of 1 thread and uses a SynchronousQueue which blocks until the worker thread consumes the job:
final ExecutorService executorServer =
new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
But if that was the case then you would just call the task directly inside of a synchronized block and you wouldn't need the ExecutorService.
Lastly, for any new concurrency programmer (of any language) I would recommend that you take the time to read some documentation on the subject. Until you start recognizing the concurrent pitfalls inherent in threading even the simplest set of classes, it will be a frustrating process to get your code to work. Doug Lea's book is one of the bible's on the subject. My apologies if I have underestimated your experience in this area.
I think you should not have "synchronized" on the esperar method. That will block using the object instances as the locking object. Any other thread that attempts to wait will block AT ENTRY TO THE METHOD, not on the wait. So, the notifyAll will release the one thread that got into the method first. Of the remaining callers, only one will proceed with a call to esperar, which will then block on the wait(). Rinse and repeat.
ExectutorService is the way to go. But if you want to do-it-yourself, or need to do something fancier, I offer the following.
I gather than this whole thing is driven by Equip's queueCommand, which might be callled from any thread anywhere at any time. For starters, the two methods in Equip should by synchronized so commandQueue does not get trashed. (You might use ConcurrentLinkedQueue, but be careful with your counts.) Better still, put the code in each method in a block synchronized by queueCommand.
But further, I think your two classes work better combined. Switching Command to a simple Runnable, I'd try something like this:
class Equip {
private Object queueLock = new Object(); // Better than "this".
private LinkedList<Runnable> commandQueue = new LinkedList<Runnable>();
private void run() {
for (;;) {
Runnable cmd = equip.getNextCommand();
if (cmd == null) {
// Nothing to do.
synchronized (queueLock) { queueLock.wait(); }
}
else
cmd.run();
}
}
// Adds commands to run.
public boolean queueCommand( Runnable cmd ) {
synchronized (queueCommand) { commandQueue.addLast( cmd ); }
synchronized (queueLock) {
// Lets "run" know queue has something in it if it
// is in a wait state.
queueLock.notifyAll();
}
}
private Runnable getNextCommand() {
synchronized (queueCommand) { return commandQueue.pollFirst(); }
}
}
You'll need to catch some exceptions, and figure out how to start things up and shut them down, but this should give an idea of how the wait and notify work. (I'd look for some way to know when "run" was not waiting so I could skip synching on queueLock in queueCommand, but walk before you run.)

Categories