Consider this code:
class Solver {
private boolean abort = false;
public void solve(List<Case> cases) {
while(!abort) {
for(Case c : cases)
compute(c); // method that take too long to finish
}
}
// a bunch of methods
public void abort() {
abort = true;
}
}
// in another class
Solver solver = new Solver();
solver.solve(cases);
public void onSolveAborted() {
solver.abort();
}
How can I change this solution so I can abort the solve function instantly. I know I can implements the Runnable interface in Solver class so I can stop the thread. This will introduce many changes in our code and I don't know if the framework we are using allow creating threads.
This will not be possible without the use of threads. Something has to set abort() before the running thread will stop. Take a look at this example:
class Solver implements Runnable {
private List<Case> cases;
public Solver(List<Case> cases) {
this.cases = cases;
}
private void compute(Case c) {
try {
// Do some computation here
} finally {
// Sound the horns! Abandon ship!
}
}
public void solve(List<Object> cases) {
for (Case c : cases) {
try {
compute(c); // method that take too long to finish
} catch (InterruptedException e) {
// Hmm, maybe I should take the hint...
break;
}
}
}
public void run() {
solve(cases);
}
public static void main(String args[]) {
List<Case> cases = new ArrayList<Case>();
// Populate cases
Thread t = new Thread(new Solver(cases));
t.run();
do {
// Wait 30 seconds
t.join(30 * 1000);
// Not done yet? Lets drop a hint..
if(t.isAlive()) {
t.interrupt();
}
} while (t.isAlive());
}
}
Very simply, it launches solve in a thread. The main thread waits up to 30 seconds then interrupts solve method. The solve method catches the interruption and gracefully exits the computation. Unlike your solution using boolean abort, this launches an InterruptedException from anywhere in your thead code (and you should deal with the exception accordingly!) allowing you to halt execution at any time.
If you want more control, you can add the try.. catch inside compute so you can have a finally clause to close any opened files or whatnot. Perhaps better still, have a try.. finally in compute to deal with closing things in a "nice" way and the try.. catch (InterruptedException) in the solve method to handle what happens in the case of interruption (in short, cleanup logic and interruption logic don't have to be in the same method).
Do somthing like this
Let say, you have 100 cases, 10 has been solved and you want to abort remaing 90.
In your code, you are solving all the cases in one iteration, after that while loop check for abort.
public void solve(List<Case> cases) {
Iterator<Case> iterator = cases.iterator();
while (iterator.hasNext() && !abort) {
Case c=iterator.iterator.next();
compute(c);
}
}
Change your class to Runnable and use ExecutorService to run it. Then you can just use methods "shutDown()" or "shutDownNow()" methods. This is cleaner and less intrusive then what you suggested in your own question. Plus killing thread manually is a REALLY BAD idea. At some point in JDK itself in thread method "kill()" was killed as there is no clean way to do so properly
Related
I have an AutoCloseable whose close() method is being called prematurely. The AutoCloseable is ProcessQueues below. I don't want the close() method to be called when it is currently being called. I'm considering the removal of "implements AutoCloseable" to accomplish that. But then how do I know when to call ProcessQueues.close()?
public class ProcessQueues implements AutoCloseable {
private ArrayList<MessageQueue> queueObjects = new ArrayList<MessageQueue>();
public ProcessQueues() {
queueObjects.add(new FFE_DPVALID_TO_SSP_EXCEPTION());
queueObjects.add(new FFE_DPVALID_TO_SSP_ESBEXCEPTION());
...
}
private void scheduleProcessRuns() {
try {
for (MessageQueue obj : queueObjects) {
monitorTimer.schedule(obj, new Date(), 1); // NOT THE ACTUAL ARGUMENTS
}
}
catch (Exception ex) {
// NOT THE ACTUAL EXCEPTION HANDLER
}
}
public static void main(String[] args) {
try (ProcessQueues pq = new ProcessQueues()) {
pq.scheduleProcessRuns();
} catch (Exception e) {
// NOT THE ACTUAL EXCEPTION HANDLER
}
}
#Override
public void close() throws Exception {
for (MessageQueue queue : queueObjects) {
queue.close();
}
}
}
I want ProcessQueues.close() to be called, but not until the task execution threads of all Timer objects terminate. As written, ProcessQueues.close() will be called as soon as the tasks are scheduled. I can easily solve that by removing "implements AutoCloseable" from the ProcessQueues class (and removing the #Override annotation). But then I have to call ProcessQueues.close() myself. How do I know when the task execution threads of all Timer objects have terminated? That's when I want to call ProcessQueues.close().
Note that MessageQueue isn't instantiated in the resource specification header of a try-with-resources block, so although MessageQueue also implements AutoCloseable, the feature isn't utilized here. I'm explicitly calling MessageQueue.close(). It is in MessageQueue.close() that I release resources. Releasing those resources prematurely causes the task execution threads to fail to complete their tasks.
I'm considering an explicit call to ProcessQueues.close() after rewriting the code to prevent automatic resource deallocation, but again I don't know how to discover the right time for that explicit call.
I considered overriding ProcessQueues.finalize(), but "Java: How to Program", Eleventh Edition advises against that. "You should never use method finalize, because it can cause many problems and there's uncertainty as to whether it will ever get called before a program terminates... Now it's considered better practice for any class that uses system resources... to provide a method that programmers can call to release resources when they're no longer needed in a program." I have such a method. It's ProcessQueues.close(). But when should I call it?
You have conflicting lifecycle issues here.
You have Timer whose lifecycle is 100% in your control. You start it, you stop it, and that's it. But you have no direct introspection in to the status of the threads being managed by the Timer. So, you can't ask it if it has anything currently running, for example.
Then you have your MessageQueue, which is invoked by the Timer. This is the lifecycle you're interested in. You want to wait for all of the MessageQueues to be "done", for assorted values of done. But, since the queue are constantly being rescheduled (given the Timer.schedule method that you're using), they're NEVER "done". They process their contents and go off and run again.
So, how is anyone to know when "done" means "done"?
Is it up to the MessageQueue? Or is it up to the ProcessQueues? Who's in command here?
Notice, nothing ever cancels the Timer. It's just runs on and on and on.
So, how can one know when MessageQueue can be closed?
If MessageQueue is the real driver here, then you should add lifecycle methods to the MessageQueue that ProcessQueues can monitor to know when to shut things down. For example, you could create a CountDownLatch set for however many MessageQueues are in your list, and then subscribe to a new lifecycle method on the MessageQueue that it calls when it's finished. The callback method can then decrement the CountDownLatch, and the ProcessQueues.close method simply waits on the latch to countdown before closing everything.
public class ProcessQueues implements AutoCloseable, MessageQueueListener {
private ArrayList<MessageQueue> queueObjects = new ArrayList<MessageQueue>();
CountDownLatch latch;
public ProcessQueues() {
queueObjects.add(new FFE_DPVALID_TO_SSP_EXCEPTION());
queueObjects.add(new FFE_DPVALID_TO_SSP_ESBEXCEPTION());
...
queueObjects.forEach((mq) -> {
mq.setListener(this);
});
latch = new CountDownLatch(queueObjects.size());
}
private void scheduleProcessRuns() {
try {
for (MessageQueue obj : queueObjects) {
monitorTimer.schedule(obj, new Date(), 1); // NOT THE ACTUAL ARGUMENTS
}
} catch (Exception ex) {
// NOT THE ACTUAL EXCEPTION HANDLER
}
}
public static void main(String[] args) {
try (ProcessQueues pq = new ProcessQueues()) {
pq.scheduleProcessRuns();
} catch (Exception e) {
// NOT THE ACTUAL EXCEPTION HANDLER
}
}
#Override
public void close() throws Exception {
latch.await();
for (MessageQueue queue : queueObjects) {
queue.close();
}
monitorTimer.cancel();
}
#Override
public void messageQueueDone() {
latch.countDown();
}
}
public interface MessageQueueListener {
public void messageQueueDone();
}
public class MessageQueue extends TimerTask {
MessageQueueListener listener;
public void setListener(MessageQueueListener listener) {
this.listener = listener;
}
private boolean isMessageQueueReallyDone {
...
}
public void run() {
...
if (isMessageQueueReallyDone() && listener != null) {
listener.messageQueueDone();
}
}
}
Mind, this means that your try-with-resource block will block waiting on all of the MessageQueues, if that's what you want, then you're good to go.
It also crassly assumes that your MessageQueue.run() knows when to shut down, which goes back to that "who's in control here" thing.
I could terminate the Timer, but having it run perpetually is intentional. The question is in consideration of what happens when something else terminates the Timer and the MessageQueue objects are no longer needed. It is at that point that I would like to call ProcessQueues.close().
If I were to use the Executor framework, rather than Timer, then I could use ExecutorService.awaitTermination(long timeout, TimeUnit unit)
TimerTask is a Runnable, and MessageQueue is already a TimerTask, so MessageQueue need not change.
'ExecutorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS)' would effectively wait forever for termination.
public static void main(String[] args) {
try (ProcessQueues pq = new ProcessQueues()) {
pq.scheduleProcessRuns();
// Don't take this literally.
ExecutorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (Exception e) {
// NOT THE ACTUAL EXCEPTION HANDLER
}
}
Of course, awaitTermination isn't a static method, so I'll have to have an ExecutorService, but you get the idea.
After termination, the AutoCloseable feature is leveraged and ProcessQueues.close() is implicitly called.
All that remains is to start the threads for perpetually repeated calls to each TimerTask, using the Executor framework. The answer to that question is ScheduledExecutorService.
I think this will work.
I have a Thread that only has to work when a certain circumstance comes in. Otherwise it just iterates over an empty infinite loop:
public void run() {
while(true) {
if(ball != null) {
// do some Calculations
}
}
}
Does it affect the performance when the loop actually does nothing but it has to check if it has to do the calculation every iteration?
Only creating a this Thread when needed is not an option for me, because my class which implements Runnable is a visual object which has be shown all the time.
edit: so is the following a good solution? Or is it better to use a different method (concerning performance)?
private final Object standBy = new Object();
public void run() {
while(true) {
synchronized (standBy) {
while(ball != null) // should I use while or if here?
try{ standBy.wait() }
catch (InterruptedException ie) {}
}
if(ball != null) {
// do some Calculations
}
}
public void handleCollision(Ball b) {
// some more code..
ball = b;
synchronized (standBy) {
standBy.notify();
}
}
You might want to consider putting the thread to sleep and only waking it up only when your 'ball' variable becomes true. There are multiple ways of doing this, from using the very low level, wait and notify statements to using the java.util.concurrent classes which provide a less error prone way of doing this. Have a look at the documentation for the condition interface. A data structure like a BlockingQueue would also be a solution.
Yes it does. This is the most simple implementation of busy waiting, and should be avoided whenever possible. Use wait/notify or java.util.concurrent mechanisms. Maybe you should be more specific about what exactly you want to achieve to get more useful responses.
Yes, it will certainly affect performance. To increase performance, you can consider putting in a bit of a time delay (say 500ms or 1000ms or even higher) in your code depending how crucial timing is to you.
Share a BlockingQueue between your threads.
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
I found the following interesting thing. In task manager, running that infinite loop like that, would consume 17% of my CPU. Now, if I added a simple
Thread.sleep(1)
inside the loop, which is only one milisecond, the CPU use dropped to almost zero as if I was not using the program, and the response time of the program was still pretty good on average (in my case it needed to reply things fast)
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.
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
}
}
I have a class proposing translations utilities. The translations themselves should be reloaded every 30 minutes. I use Spring Timer support for that. Basically, my class looks like :
public interface Translator {
public void loadTranslations();
public String getTranslation(String key);
}
loadTranslations() can be pretty long to run, so while it is running the old translations are still available. This is done by loading the translations in a local Map and just changing the reference when all translations are loaded.
My problem is : how do I make sure that when a thread is already loading translations, is a second one also tries to run, it detects that and returns immediately, without starting a second update.
A synchronized method will only queue the loads ... I'm still on Java 1.4, so no java.util.concurrent.
Thanks for your help !
Use some form of locking mechanism to only perform the task if it is not already in progress. Acquiring the locking token must be a one-step process. See:
/**
* #author McDowell
*/
public abstract class NonconcurrentTask implements Runnable {
private boolean token = true;
private synchronized boolean acquire() {
boolean ret = token;
token = false;
return ret;
}
private synchronized void release() {
token = true;
}
public final void run() {
if (acquire()) {
try {
doTask();
} finally {
release();
}
}
}
protected abstract void doTask();
}
Test code that will throw an exception if the task runs concurrently:
public class Test {
public static void main(String[] args) {
final NonconcurrentTask shared = new NonconcurrentTask() {
private boolean working = false;
protected void doTask() {
System.out.println("Working: "
+ Thread.currentThread().getName());
if (working) {
throw new IllegalStateException();
}
working = true;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!working) {
throw new IllegalStateException();
}
working = false;
}
};
Runnable taskWrapper = new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
shared.run();
}
}
};
for (int i = 0; i < 100; i++) {
new Thread(taskWrapper).start();
}
}
}
I am from a .net background(no java experience at all), but you could try a simple static flag of some sort that checks at the beginning of the method if its alrady running. Then all you need to do is make sure any read/write of that flag is synchronized. So at beginning check the flag, if its not set, set it, if it is set, return. If its not set, run the rest of the method, and after its complete, unset it. Just make sure to put the code in a try/finally and the flag iunsetting in the finally so it always gets unset in case of error. Very simplified but may be all you need.
Edit: This actually probably works better than synchronizing the method. Because do you really need a new translation immediately after the one before it finishes? And you may not want to lock up a thread for too long if it has to wait a while.
Keep a handle on the load thread to see if it's running?
Or can't you just use a synchronized flag to indicate if a load is in progress?
This is actually identical to the code that is required to manage the construction of a Singleton (gasp!) when done the classical way:
if (instance == null) {
synchronized {
if (instance == null) {
instance = new SomeClass();
}
}
}
The inner test is identical to the outer test. The outer test is so that we dont routinely enter a synchronised block, the inner test is to confirm that the situation has not changed since we last made the test (the thread could have been preempted before entering Synchronized).
In your case:
if (translationsNeedLoading()) {
synchronized {
if (translationsNeedLoading()) {
loadTranslations();
}
}
}
UPDATE: This way of constructing a singleton will not work reliably under your JDK1.4. For explanation see here. However I think you are you will be OK in this scenario.