I'm using the below implementation to stop a thread in Tomcat. The code works, but I'm wondering two things:
Is it necessary to have Thread.sleep() in the try statement of MyConsumer.java?
Instead of checking for my boolean flag, running, should I remove the concept of a flag and just check for while(!Thread.currentThread().isInterrupted)?
ServletContextListener:
public final class ApplicationListener implements ServletContextListener {
private Thread thread = null;
private MyConsumer k = null;
public ApplicationListener() {
}
#Override
public void contextInitialized(ServletContextEvent event) {
k = new MyConsumer();
thread = new Thread(k);
thread.start();
}
#Override
public void contextDestroyed(ServletContextEvent event) {
if (thread != null) {
k.terminate();
try {
thread.join();
} catch (InterruptedException ex) {
Logger.getLogger(ApplicationListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
MyConsumer.java:
public class MyConsumer implements Runnable {
private volatile boolean running = true;
public MyConsumer() {
}
public void terminate() {
running = false;
}
#Override
public void run() {
while (running) {
try {
doStuff();
Thread.sleep((long) 1000);
} catch (InterruptedException ex) {
Logger.getLogger(MyConsumer.class.getName()).log(Level.SEVERE, null, ex);
running = false;
}
}
}
Is it necessary to have Thread.sleep() in the try statement of MyConsumer.java
No. The sleep call, I presume, is there to make sure that doStuff() is executed with an interval of 1 second between every invocation, rather than executed continuously. If you want this 1 second interval, you need to leave the sleep call there. If you want doStuff() to be executed continuously, then you need to remove the sleep.
Instead of checking for my boolean flag, running, should I remove the concept of a flag and just check for while(!Thread.currentThread().isInterrupted)?
Yes, that's what I would indeed do. It would remove the need for the flag, and would allow stopping the thread as soon as possible, rather than having to wait for the sleep call to return, after 1 second. The other advantage is that you can check if the thread is interrupted inside the doStuff() method, in case it's a long-running method that you want to stop ASAP.
There's no reason for your thread to sleep just to check for interruptions. You can call Thread.interupted() there instead.
Regarding the boolean running flag, it provides similar functionality of interrupted, except that it's not triggered by methods that throw InterruptedException. Depending on whether it makes sense to stop normal flow of operation in those methods, you should use one or the other mechanism, but not both.
See http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html for a good overview of how interrupts are used.
Related
I have following class:
public class PawnThread implements Runnable {
public void start() {
thread.start();
}
#Override
public void run() {
try {
while (... some finish condition ...) {
move();
synchronized (this) {
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.err.println(pawn.toString() + ": thread interrupted :(");
}
}
void move() {
... some blocking actions
}
synchronized void suspend() {
suspendFlag = true;
}
synchronized void resume() {
suspendFlag = false;
notify();
}
}
Now I have a list of its objects:
private final List<PawnThread> pawnThreadList;
I defined some helper method to suspend all of them:
public void suspendAll() {
pawnThreadList.forEach(PawnThread::suspend);
}
Now suspend() method is only about changing flag. The requirement is, that when I leave suspendAll() method, all threads should be actually paused (they cannot be in RUNNABLE state) - for now it is not a case, beacause for some of them, it may take some time to actually finish their job before pause.
I would be grateful for advice what is correct design for this soulution.
Regards
Make PawnThread#suspend() wait for suspension to be completed:
public class PawnThread implements Runnable {
private final Waiter suspender = new Waiter();
private final Waiter suspending = new Waiter();
#Override
public void run() {
try {
while (...) {
suspending.suspend();
move();
suspending.resume();
suspender.await();
}
} catch (InterruptedException e) {
...
}
}
void suspend() throws InterruptedException {
suspender.suspend();
suspending.await();
}
void resume() {
suspender.resume();
}
}
public class Waiter {
private boolean waiting;
public synchronized void await() throws InterruptedException {
while (waiting) {
wait();
}
}
public synchronized void suspend() {
waiting = true;
}
public synchronized void resume() {
waiting = false;
notify();
}
}
The requirement is impossible to satisfy, but also makes no sense. In order for the thread to communicate the fact that it has suspended, the thread must be running. There is no way to ensure the thread has completed the suspension process.
But this is also not a sensible requirement. How can it possibly matter whether the thread has suspended itself or is about to suspend itself, so long as it has nothing left to do but suspend itself?
A sensible requirement should be satisfied by having each thread set some indication somewhere that it has received the suspend request and is about to stop executing. Then the calling thread can wait for all threads to have provided that indication.
Universal correct design for any parallel solution is to define streams of tokens and firing rule (see Petry Net tedminology). Most simple and useful firing rule is to start an action when all input tokens are ready. I your case, input tokens are hidden in whle condition and in suspend condition. Your mistake is you defined suspend condition as negative, while all tokens must be defined as positive. That is, a thread works where there are enough tokens, and stops when they are exhausted, and then thread waits while the number of tokens is increased by external threads.
Tokens may be of 2 kinds - black (pure permissions), passed by Semaphores, and color (messages), passed by BlockingQueues. These 2 communicator classes cover most of use cases. In some complex cases, user can create custom communicators using synchronized/wait/notify.
So canonical way to design any parallel program is as follows:
design Petry Net, with places for tokens (communicators), and transitions (actions).
map places to Semaphores/BlockingQueues/CustomCommunicators, and transition to threads (or Actors).
Consider the following (simplified) class, designed to allow my entire component to enter some interim state before completely stopping. (The purpose of the interim state is to allow the component to complete its existing tasks, but reject any new ones).
The component might be started and stopped multiple times from any number of threads.
class StopHandler {
boolean isStarted = false;
synchronized void start() {isStarted = true;}
//synchronized as I do want the client code to block until the component is stopped.
//I might add some async method as well, but let's concentrate on the sync version only.
synchronized void stop(boolean isUrgent) {
if (isStarted) {
if (!isUrgent) {
setGlobalState(PREPARING_TO_STOP); //assume it is implemented
try {Thread.sleep(10_000L);} catch (InterruptedException ignored) {}
}
isStarted = false;
}
}
The problem with the current implementation is that if some client code needs to urgently stop the component while it is in the interim state, it will still have to wait.
For example:
//one thread
stopHandler.stop(false); //not urgent => it is sleeping
//another thread, after 1 millisecond:
stopHandler.stop(true); //it's urgent, "please stop now", but it will wait for 10 seconds
How would you implement it?
I might need to interrupt the sleeping thread, but I don't have the sleeping thread object on which to call 'interrupt()'.
How about storing a reference to current Thread (returned by Thread.currentThread()) in a field of StopHandler directly before you call sleep? That would allow you you to interrupt it in the subsequent urgent call in case the Thread is still alive.
Couldn't find a better solution than the one suggested by Lars.
Just need to encapsulate the sleep management for completeness.
class SleepHandler {
private final ReentrantLock sleepingThreadLock;
private volatile Thread sleepingThread;
SleepHandler() {
sleepingThreadLock = new ReentrantLock();
}
void sleep(long millis) throws InterruptedException {
setSleepingThread(Thread.currentThread());
Thread.sleep(millis);
setSleepingThread(null);
}
void interruptIfSleeping() {
doWithinSleepingThreadLock(() -> {
if (sleepingThread != null) {
sleepingThread.interrupt();
}
});
}
private void setSleepingThread(#Nullable Thread sleepingThread) {
doWithinSleepingThreadLock(() -> this.sleepingThread = sleepingThread);
}
private void doWithinSleepingThreadLock(Runnable runnable) {
sleepingThreadLock.lock();
try {
runnable.run();
} finally {
sleepingThreadLock.unlock();
}
}
}
With this helper class, handling of the original problem is trivial:
void stop(boolean isUrgent) throws InterruptedException {
if (isUrgent) {sleepHandler.interruptIfSleeping();} //harmless if not sleeping
try {
doStop(isUrgent); //all the stuff in the original 'stop(...)' method
} catch (InteruptedException ignored) {
} finally {
Thread.interrupted(); //just in case, clearing the 'interrupt' flag as no need to propagate it futher
}
I have been looking for ways to kill a thread and it appears this is the most popular approach
public class UsingFlagToShutdownThread extends Thread {
private boolean running = true;
public void run() {
while (running) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
System.out.println("Shutting down thread");
}
public void shutdown() {
running = false;
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.shutdown();
}
}
However, if in the while loop we spawn another another object which gets populated with data (say a gui that is running and updating) then how do we call back - especially considering this method might have been called several times so we have many threads with while (running) then changing the flag for one would change it for everyone?
thanks
One approach with these problems is to have a Monitor class which handles all the threads. It can start all necessary threads (possibly at different times/when necessary) and once you want to shutdown you can call a shutdown method there which interrupt all (or some) of the threads.
Also, actually calling a Threads interrupt() method is generally a nicer approach as then it will get out of blocking actions that throw InterruptedException (wait/sleep for example). Then it will set a flag that is already there in Threads (which can be checked with isInterrupted() or checked and cleared with interrupted(). For example the following code can replace your current code:
public class UsingFlagToShutdownThread extends Thread {
public void run() {
while (!isInterrupted()) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { interrupt(); }
}
System.out.println("Shutting down thread");
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
i added a utlility class which essentially had a static map and methods.
the map was of type Long id, Thread thread. I added two methods one to add to the map and one to stop the thread via the use of interrupt. This method took the id as a parameter.
I also changed my loop logic from while true, too while ! isInterrupted. Is this approach ok or is this bad programming style/convention
thanks
I have a certain function in my program that I want to stop on the press of a key. I have a native keyboard hook set up for that purpose. Right now, I call System.exit(0) when that key is detected. However, I don't want to exit the program, just stop that operation and return to where it was called. An example is given below.
public class Main {
public static void main(String[] args) {
System.out.println("Calling function that can be stopped with CTRL+C");
foo(); // Should return when CTRL+C is pressed
System.out.println("Function has returned");
}
}
I've tried putting the call to foo() in a thread so I could call Thread.interrupt() but I want the function call to be blocking, not non-blocking. Also there are blocking IO calls in foo() so I'd rather not deal with interrupts unless it's necessary, because I'd have to deal with ClosedByInterruptException exceptions and that has caused problems before.
Also the body of foo() is very long and has many function calls inside it, so writing if (stop == true) return; in the function is not an option.
Is there a better way to do this than making a blocking thread? If so, how? If not, how would I make a blocking thread?
How about this?
// Create and start the thread
MyThread thread = new MyThread();
thread.start();
while (true) {
// Do work
// Pause the thread
synchronized (thread) {
thread.pleaseWait = true;
}
// Do work
// Resume the thread
synchronized (thread) {
thread.pleaseWait = false;
thread.notify();
}
// Do work
}
class MyThread extends Thread {
boolean pleaseWait = false;
// This method is called when the thread runs
public void run() {
while (true) {
// Do work
// Check if should wait
synchronized (this) {
while (pleaseWait) {
try {
wait();
} catch (Exception e) {
}
}
}
// Do work
}
}
}
(taken from http://www.exampledepot.com/egs/java.lang/PauseThread.html not my own work)
I'm using a thread that is continuously reading from a queue.
Something like:
public void run() {
Object obj;
while(true) {
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
obj = objectesQueue.poll();
}
}
// Do something with the Object obj
}
}
What is the best way to stop this thread?
I see two options:
1 - Since Thread.stop() is deprecated, I can implement a stopThisThread() method that uses a n atomic check-condition variable.
2 - Send a Death Event object or something like that to the queue. When the thread fetches a death event, it exits.
I prefer the 1st way, however, I don't know when to call the stopThisThread() method, as something might be on it's way to the queue and the stop signal can arrive first (not desirable).
Any suggestions?
The DeathEvent (or as it is often call, "poison pill") approach works well if you need to complete all of the work on the queue before shutting down. The problem is that this could take a long time.
If you want to stop as soon as possible, I suggest you do this
BlockingQueue<O> queue = ...
...
public void run() {
try {
// The following test is necessary to get fast interrupts. If
// it is replaced with 'true', the queue will be drained before
// the interrupt is noticed. (Thanks Tim)
while (!Thread.interrupted()) {
O obj = queue.take();
doSomething(obj);
}
} catch (InterruptedException ex) {
// We are done.
}
}
To stop the thread t that instantiated with that run method, simply call t.interrupt();.
If you compare the code above with other answers, you will notice how using a BlockingQueue and Thread.interrupt() simplifies the solution.
I would also claim that an extra stop flag is unnecessary, and in the big picture, potentially harmful. A well-behaved worker thread should respect an interrupt. An unexpected interrupt simply means that the worker is being run in a context that the original programmer did not anticipate. The best thing is if the worker to does what it is told to do ... i.e. it should stop ... whether or not this fits with the original programmer's conception.
Why not use a scheduler which you simply can stop when required? The standard scheduler supports repeated scheduling which also waits for the worker thread to finish before rescheduling a new run.
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleWithFixedDelay(myThread, 1, 10, TimeUnit.SECONDS);
this sample would run your thread with a delay of 10 sec, that means when one run finishes, it restarts it 10 seconds later. And instead of having to reinvent the wheel you get
service.shutdown()
the while(true) is not necessary anymore.
ScheduledExecutorService Javadoc
In your reader thread have a boolean variable stop. When you wish for this thread to stop set thius to true and interrupt the thread. Within the reader thread when safe (when you don't have an unprocessed object) check the status of the stop variable and return out of the loop if set. as per below.
public class readerThread extends Thread{
private volitile boolean stop = false;
public void stopSoon(){
stop = true;
this.interrupt();
}
public void run() {
Object obj;
while(true) {
if(stop){
return;
}
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(stop){
return;
}
obj = objectesQueue.poll();
// Do something with the Object obj
}
}
}
}
public class OtherClass{
ThreadReader reader;
private void start(){
reader = ...;
reader.start();
}
private void stop(){
reader.stopSoon();
reader.join(); // Wait for thread to stop if nessasery.
}
}
Approach 1 is the preferred one.
Simply set a volatile stop field to true and call interrupt() on the running thread. This will force any I/O methods that wait to return with an InterruptedException (and if your library is written correctly this will be handled gracefully).
I think your two cases actually exhibit the same potential behavior. For the second case consider Thread A adds the DeathEvent after which Thread B adds a FooEvent. When your job Thread receives the DeathEvent there is still a FooEvent behind it, which is the same scenario you are describing in Option 1, unless you try to clear the queue before returning, but then you are essentially keeping the thread alive, when what you are trying to do is stop it.
I agree with you that the first option is more desirable. A potential solution would depend on how your queue is populated. If it is a part of your work thread class you could have your stopThisThread() method set a flag that would return an appropriate value (or throw Exception) from the enqueuing call i.e.:
MyThread extends Thread{
boolean running = true;
public void run(){
while(running){
try{
//process queue...
}catch(InterruptedExcpetion e){
...
}
}
}
public void stopThisThread(){
running = false;
interrupt();
}
public boolean enqueue(Object o){
if(!running){
return false;
OR
throw new ThreadNotRunningException();
}
queue.add(o);
return true;
}
}
It would then be the responsibility of the object attempting to enqueue the Event to deal with it appropriately, but at the least it will know that the event is not in the queue, and will not be processed.
I usually put a flag in the class that has the Thread in it and in my Thread code I would do. (NOTE: Instead of while(true) I do while(flag))
Then create a method in the class to set the flag to false;
private volatile bool flag = true;
public void stopThread()
{
flag = false;
}
public void run() {
Object obj;
while(flag) {
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
obj = objectesQueue.poll();
}
}
// Do something with the Object obj
}
}