ensuring that all threads finish before JVM completely terminates - multithreading

Let's say I have a SwingWorker object and it's still in its doInBackground() method. If a user calls system.exit(0)...how do I best ensure that the SwingWorker daemon/worker thread completes? I imagine that I have to do this manually. The best idea I have at the moment is to call join() on all outstanding worker threads in/on the same thread that calls System.exit(0)...is this correct?
AND, if using join() is a good idea...should I use it in some sort of while loop in the case that the thread calling join() has spurious activity?
For instance:
//pseudocode
Vector<Thread> threadsThatMustFinishBeforeTerminatingJVM = new Vector<Thread>();
Thread closingThread = new Thread(){
public void run(){
for(Thread t: threadsThatMustFinishBeforeTerminatingJVM){
// closingThread waits for t to finish, (is this *really* safe?)
t.join();
}
System.exit(0);
}
}
closingThread.start();
Is this at all correct?

Take a look here
"The System.exit method forces termination of all threads in the Java virtual machine."
If you call system.exit you're basically saying, "exit now, I don't care what's going on." If you want to shut down cleanly you're going to need to set us some kind of coordination/synchronization between your threads.
If your doInBackground method is still active you could wait until it completes before exiting, some synchronization primitive, shared lock, or some such.
You can add some logic in the done() method of your SwingWorker that would allow an exit.
The better way is probably to query getState() on your SwingWorker. It'll return DONE if the task has completed and if so you can exit, otherwise just wait.

Related

Calling the instance to the thread inside that same thread

Context:
I have a cmd application in java which is written to work in peer-to-peer mode in different servers. Once a server starts, all other instances must stop. So I have written a piece of code that runs in a low priority thread and monitors an AtomicBoolean value autoClose, and whenever autoClose is set to true, thread will close application. (P.S.: I don't want to manually add close because the application has 2 main high priority threads and many temporary normal priority threads).
Here is the code:
/**
* Watches autoClose boolean value and closes the connector once it is true
* <p>
* This is a very low priority thread which continuously monitors autoClose
*/
protected void watchAndClose() {
Thread watchAutoClose = new Thread(() -> {
while (true) {
if (autoClose.get()) {
close();
// wait till closing is successful
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ignored) {
// I want instance of thread watchAutoClose so I can call this
// watchAutoClose.interrupt();
}
if (!component.getStatus()) setAutoClose(false);
}
}
});
watchAutoClose.setPriority(Thread.MIN_PRIORITY);
watchAutoClose.start();
}
Question:
SonarLint says I can't leave InterruptedException part empty. I have to either throw it again or call thatThread.interrupt().
So how can I do this? I want an instance of thread watchAutoClose inside that thread so I can call watchAutoClose.interrupt(). I tried Thread.currentThread() but I fear with that many threads, the currently executing thread wouldn't be this thread. (i.e, there is a possibility of JVM can choose to switch to another thread by the time it is inside the catch clause and calls Thread.currentThread() so at that time current thread would be the other one and I would interrupt that other thread... correct me if I am too worrying or my concept is totally wrong.)
Or should I ignore the warning altogether and leave catch block?
First of all, it’s not clear why you think that waiting for a second was necessary at all. By the time, the close() method returns, the close() method has been completed. On the other hand, if close() truly triggers some asynchronous action, there is no guaranty that waiting one second will be sufficient for its completion.
Further, addressing your literal question, Thread.currentThread() always return the calling thread’s instance. It’s impossible for a thread to execute that method without being in the running state. When a task switch happens, the thread can’t read the reference at all, until it gets CPU time again. Besides that, since the specification says that this method returns the Thread instance representing the caller, the environment has to ensure this property, regardless of how it implements it. It works even when multiple threads call this method truly at the same time, on different CPU cores.
So, regardless of how questionable the approach of waiting a second is, handling interruption like
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
is a valid approach.
But you may also replace this code with
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
The parkNanos method will return silently on interruption, leaving the calling thread in the interrupted state. So it has the same effect as catching the InterruptedException and restoring the interrupted state, but is simpler and potentially more efficient as no exception needs to be constructed, thrown, and caught.
Another point is that you are creating a polling loop on the atomic variable consuming CPU cycles when the variable is false, which is discouraged, even when you give the thread a low priority.

Why wait() method from QWaitCondition always takes a QMutex as parameter?

I am trying to pause my thread waiting for an user action. I know I could use Qt::BlockingQueuedConnection but that is not the point here. I would like to use QWaitCondition but I don't understand in this particular case why I need a QMutex.
Consider this code :
class MyWorker: public QThread
{
private:
QMutex mDummy;
QWaitCondition mStep1;
void doStuff1(){}
void doStuff2(){}
signals:
void step1Finished();
public:
MyWorker(...): {}
protected:
void run()
{
doStuff1();
emit step1Finished();
mDummy.lock();
mStep1.wait(mDummy);
mDummy.unlock();
doStuff2();
}
}
In this case the QMutex mDummy seems useless to me. I use it only because wait() need it as parameter.
I know that wait() unlock the mutex then (re)lock it after waking up, but why there no possibility to use wait() without it?
First of all, wait condition needs a mutex, so you gotta give it one. That's what a wait condition is. It is the most low level signalling mechanism between threads in multi-threading, so it doesn't provide the "convenience" you seem to be looking for.
But you also need the mutex to get things work right. A wait condition might have a spurious wakeup, that is it could be woken up for "no reason" (google "wait condition spurious wakeup" to learn more). So you have to have some condition in there to check, and keep waiting if it's still not time to continue. And to avoid race conditions, that check has to be protected by mutex.
Snippets:
// wait
mDummy.lock();
mStopWaiting = false; // maybe here, if you want to make sure this waits in all cases
while (!mStopWaiting)
{
// note that wait releases the mutex while waiting
mStep1.wait(&mDummy);
}
mDummy.unlock();
// signal end of wait
mDummy.lock();
mStopWaiting = true;
mStep1.wakeOne(); // or wakeAll() maybe depending on other code
mDummy.unlock();
As you can see, that mutex isn't so dummy after all. Note that all access to mStopWaiting has to be protected by this mutex, not just here.
Imagine you want to wait for something to happen. Since that something has to happen in another thread (since this thread is waiting) it has to be protected in some way to avoid race conditions.
Imagine you use the following code:
Acquire a lock.
Check if the thing you want to wait for has happened.
If it has, stop, you're done.
If it hasn't, wait.
Oops. We're still holding the lock. There's no way the thing we're waiting for can happen because no other thread can access it.
Let's try again.
Acquire a lock.
Check if the thing you want to wait for has happened.
If it has, stop, you're done.
If it hasn't, release the lock and wait.
Oops. What if after we release the lock but before we wait, it happens. Then we'll be waiting for something that already happened.
So what we need for step 4 is an atomic "unlock and wait" operation. This releases the lock and waits without giving another thread a chance to sneak in and change things before we can start waiting.
If you don't need an atomic "unlock and wait" operation, don't use QWaitCondition. This is its sole purpose. It takes a QMutex so it knows what to unlock. That QMutex must protect whatever it is the thread is waiting for or your code will be vulnerable to the very race condition QWaitCondition exists to solve for you.

Disabling a System.Threading.Timer instance while its callback is in progress

I am using two instances of System.Threading.Timer to fire off 2 tasks that are repeated periodically.
My question is: If the timer is disabled but at that point of time this timer is executing its callback on a thread, then will the Main method exit, or will it wait for the executing callbacks to complete?
In the code below, Method1RunCount is synchronized for read and write using lock statement ( this part of code is not shown below). The call back for timer1 increments Method1RunCount by 1 at end of each run.
static void Main(string[] args)
{
TimerCallback callback1 = Method1;
System.Threading.Timer timer1 = new System.Threading.Timer(callback1,null,0, 90000);
TimerCallback callback2 = Method2;
System.Threading.Timer timer2 = new System.Threading.Timer(callback2, null, 0, 60000);
while (true)
{
System.Threading.Thread.Sleep(250);
if (Method1RunCount == 4)
{
//DISABLE the TIMERS
timer1.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
timer2.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
break;
}
}
}
This kind of code tends to work by accident, the period of the timer is large enough to avoid the threading race on the Method1RunCount variable. Make the period smaller and there's a real danger that the main thread won't see the value "4" at all. Odds go down considerably when the processor is heavily loaded and the main thread doesn't get scheduled for while. The timer's callback can then execute more than once while the main thread is waiting for the processor. Completing missing the value getting incremented to 4. Note how the lock statement does not in fact prevent this, it isn't locked by the main thread since it is probably sleeping.
There's also no reasonable guess you can make at how often Method2 runs. Not just because it has a completely different timer period but fundamentally because it isn't synchronized to either the Method1 or the Main method execution at all.
You'd normally increment Method1RunCount at the end of Method1. That doesn't otherwise guarantee that Method1 won't be aborted. It runs on a threadpool thread, they have the Thread.IsBackground property always set to true. So the CLR will readily abort them when the main thread exits. This again tends to not cause a problem by accident.
If it is absolutely essential that Method1 executes exactly 4 times then the simple way to ensure that is to let Method1 do the counting. Calling Timer.Change() inside the method is fine. Use a class like AutoResetEvent to let the main thread know about it. Which now no longer needs the Sleep anymore. You still need a lock to ensure that Method1 cannot be re-entered while it is executing. A good way to know that you are getting thread synchronization wrong is when you see yourself using Thread.Sleep().
From the docs on System.Threading.Timer (http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx):
When a timer is no longer needed, use the Dispose method to free the
resources held by the timer. Note that callbacks can occur after the
Dispose() method overload has been called, because the timer queues
callbacks for execution by thread pool threads. You can use the
Dispose(WaitHandle) method overload to wait until all callbacks have
completed.

how to detect when a thread has completed execution in blackberry?

How can I detect when the below code/thread has completed execution in Blackberry:
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
EventInjector.KeyEvent inject = new EventInjector.KeyEvent
(EventInjector.KeyEvent.KEY_DOWN,Characters.ENTER, 0);
inject.post();
inject.post();
}
});
Can I get a notification when this thread has executed so that I can start another thread?
Thanks in advance.
Typically, the join() method is used to determine when a thread has finished. Calling join() typically blocks, so use it with care.
Here is a reference.
You need a synchronized block, here is a short description of how it works.
The "sleeping" thread must lock an object, and call wait() on it.
The other thread locks the same object, and sends a notify() or notifyAll() to wake up the first one.
If you start the thread explicitly (not in this case), you can simply call join() on it, and synchronously wait for it to finish.
- Edit: using join() on a thread
Assuming you already have a runnable object:
Thread myThread = new Thread(myRunnable);
myThread.start();
doOtherStuff();
myThread.join();
But if something goes wrong, you are stuck on the join() call, because BlackBerry has no timeout for this call.

When myThread.Start(...) is called, do we have the assurance that the thread is started?

When myThread.Start(...) is called, do we have the assurance that the thread is started? The MSDN documentation isn't really specific about that. It says that the status of is changed to Running.
I am asking because I've seen a couple of times the following code. It creates a thread, starts it and then loop until the status become Running. Is that necessary to loop?
Thread t = new Thread(new ParameterizedThreadStart(data));
t.Start(data);
while (t.ThreadState != System.Threading.ThreadState.Running &&
t.ThreadState != System.Threading.ThreadState.WaitSleepJoin)
{
Thread.Sleep(10);
}
Thanks!
If you're set on not allowing your loop to continue until the thread has "started", then it will depend on what exactly you mean by "started". Does that mean that the thread has been created by the OS and signaled to run, but not necessarily that it's done anything yet? Does that mean that it's executed one or more operations?
While it's likely fine, your loop isn't bulletproof, since it's theoretically possible that the entire thread executes between the time you call Start and when you check the ThreadState; it's also not a good idea to check the property directly twice.
If you want to stick with checking the state, something like this would/could be more reliable:
ThreadState state = t.ThreadState;
while(state != ThreadState.Runnung && state != ThreadState.WaitSleepJoin)
{
Thread.Sleep(10:
state = t.ThreadState;
}
However, this is still subject to the possibility of the thread starting, running, then stopping before you even get the chance to check. Yes, you could expand the scope of the if statement to include other states, but I would recommend using a WaitHandle to signal when the thread "starts".
ManualResetEvent signal;
void foo()
{
Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod));
signal = new ManualResetEvent();
t.Start(data);
signal.WaitOne();
/* code to execute after the thread has "started" */
}
void ThreadMethod(object foo)
{
signal.Set();
/* do your work */
}
You still have the possiblity of the thread ending before you check, but you're guaranteed to have that WaitHandle set once the thread starts. The call to WaitOne will block indefinitely until Set has been called on the WaitHandle.
Guess it depends on what you are doing after the loop. If whatever comes after it critically dependant on the thread running then checking is not a bad idea. Personnally I'd use a ManualResetEvent or something similiar that was set by the Thread rather than checking the ThreadStatus
No. Thread.Start causes a "thread to be scheduled for execution". It will start, but it may take a (short) period of time before the code within your delegate actually runs. In fact, the code above doesn't do what (I suspect) the author intended, either. Setting the thread's threadstate to ThreadState.Running (which does happen in Thread.Start) just makes sure it's scheduled to run -- but the ThreadState can be "Running" before the delegate is actually executing.
As John Bergess suggested, using a ManualResetEvent to notify the main thread that the thread is running is a much better option than sleeping and checking the thread's state.

Resources