Calling the instance to the thread inside that same thread - multithreading

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.

Related

ReleaseMutex : Object synchronization method was called from an unsynchronized block of code

I have this pretty straightforward piece of code that very rarely throws "System.ApplicationException : Object synchronization method was called from an unsynchronized block of code." when ReleaseMutex() is called.
I logically analyzed the flow of the method and just cannot understand how/why this could happen.
To my understanding, the ownership of mutex is guaranteed in this case:
readonly string mutexKey;
public Logger(string dbServer, string dbName)
{
this.mutexKey = ServiceManagerHelper.GetServiceName(dbServer, dbName);
}
private void Log(LogType type, string message, Exception ex)
{
using (var mutex = new Mutex(false, mutexKey))
{
bool acquiredMutex;
try
{
acquiredMutex = mutex.WaitOne(TimeSpan.FromSeconds(5));
}
catch (AbandonedMutexException)
{
acquiredMutex = true;
}
if (acquiredMutex)
{
try
{
// some application code here
}
finally
{
mutex.ReleaseMutex();
}
}
}
}
catch (AbandonedMutexException)
{
acquiredMutex = true;
}
This is a very serious bug in your code. Catching an AbandonedMutexException is never correct, it is a very serious mishap. Another thread acquired the mutex but terminated without calling ReleaseMutex(). You've irrecoverably lost synchronization and the mutex is no longer usable.
You were sort of lucky by making a mistake and assuming that you acquired the mutex anyway. You didn't. The ReleaseMutex() call will now bomb with the exception you quoted.
You cannot recover from this mishap, other than by terminating the program (the wise choice) or by disabling logging completely so the mutex will never be used again. Make the wise choice by removing the catch clause. Discovering the true source of the problem, that thread that crashed and didn't call ReleaseMutex(), is out of context for this question, there are no hints. You've been ignoring this problem, papered it over by catching AME, you can't ignore it.
In my case, i see the same behavior like Nathan Schubkegel. I use await's, and Thread.CurrentThread.ManagedThreadId gives another value for the "same" thread. I mean, thread was started with ManagedThreadId == 10, and Mutex was owned with this thread id, but later ReleaseMutex() causes ApplicationException with message: "Object synchronization method was called from an unsynchronized block of code", and i see that ManagedThreadId == 11 at this time :) . It seems, await sometimes changes thread id when returns. It seems, that is the reason. Mutex thinks that another thread wants to release it. It's sad, that Mutex documentation does not make ATTENTION on this moment.
So, you CAN NOT use asynchronous operator await between Mutex acquire and release. It's because C# compiler replaces plain operator await by asynchronous callback, and this callback can be made by ANOTHER thread. Usually, it's the same thread, but sometimes it's another thread (from thread pool).
Mutex checks thread. Only thread that acquired Mutex may release it. If you need synchronization without this checking, use Semaphore. SemaphoreSlim has asynchronous method WaitAsync() - it's cool.
This exception is raised when you call ReleaseMutex() from a thread that does not own the mutex. Search // some application code here for code that releases the mutex.
Also reconsider whether you're actually calling ReleaseMutex() from the same thread where you called WaitOne(). Example: I arrived at this post because I was using async/await and my code resumed on a different thread and tried to release a mutex the thread didn't own.

mutex destroyed while busy

There is a singleton object of EventHandler class to receive events from the mainthread. It registers the input to a vector and creates a thread that runs a lambda function that waits for some time before deleting the input from the vector to prevent repeated execution of the event for this input for some time.
But I'm getting mutex destroyed while busy error. I'm not sure where it happened and how it happened. I am not even sure what it meant either because it shouldn't be de-constructed ever as a singleton object. Some help would be appreciated.
class EventHandler{
public:
std::mutex simpleLock;
std::vector<UInt32> stuff;
void RegisterBlock(UInt32 input){
stuff.push_back(input);
std::thread removalCallBack([&](UInt32 input){
std::this_thread::sleep_for(std::chrono::milliseconds(200));
simpleLock.lock();
auto it = Find(stuff, input);
if (it != stuff.end())
stuff.erase(it);
simpleLock.simpleLock.unlock();
}, input)
removalCallBack.detach();
}
virtual EventResult ReceiveEvent(UInt32 input){
simpleLock.lock();
if (Find(stuff, input) != stuff.end()){
RegisterBlock(input));
//dostuff
}
simpleLock.simpleLock.unlock();
}
};
What is happening is that a thread is created
std::thread removalCallBack([&](UInt32 input){
std::this_thread::sleep_for(std::chrono::milliseconds(200));
simpleLock.lock();
...
removalCallBack.detach();
And then since removalCallBack is a local variable to the function RegisterBlock, when the function exits, the destructor for removalCallBack gets called which invokes std::terminate()
Documentation for thread destructor
~thread(); (since C++11)
Destroys the thread object. If *this still has an associated running thread (i.e. joinable() == true), std::terminate() is called.
but depending on timing, simpleLock is still owned by the thread (is busy) when the thread exits which according to the spec leads to undefined behavior, in your case the destroyed while busy error.
To avoid this error, you should either allow the thread to exist after the function exits (e.g. not make it a local variable) or block until the thread exits before the function exits using thread::join
Dealing with cleaning up after threads can be tricky especially if they are essentially used as different programs occupying the same address space, and in those cases many times a manager thread just like you thought of is created whose only job is to reclaim thread related resources. Your situation is a little easier because of the simplicity of the work done in the thread created by removalCallBack, but there still is cleanup to do.
If the thread object is going to be created by new, then although system resources used by the system thread the C++ thread object represents will get cleaned up, but the memory the object uses will remain allocated until delete is called.
Also, consider if the program exits while there are threads running, then the threads will be terminated, but if there is a mutex locked when that happens, once again there will be undefined behavior.
What is usually done to guarantee that a thread is no longer running is to join with it, but though this doesn't say, the pthread_join man page states
Once a thread has been detached, it can't be joined with pthread_join(3) or be made joinable again.

ensuring that all threads finish before JVM completely terminates

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.

System::Threading::Mutex, called from unsynchronized block of code. Unexpected deadlock

In an attempt to rid my GUI of race conditions and deadlocks I have the following function which I call from the c'tor and whenever I need the service which shares my named mutex to provide its input:
void EnvCapt::FireServiceAndOrHold() {
try {
mutTimerSyncEx->ReleaseMutex();
Thread::Sleep(100); //Time enough for the service to complete.
if (!mutTimerSyncEx->WaitOne(3 * int_ms)) {//int_ms = the polling period
//Must've been doubly locked or worse.
mutTimerSyncEx->ReleaseMutex();
FireServiceAndOrHold();
}
} catch (Exception ^ ex) {
//Released unheld mutex. Retake control.
mutTimerSyncEx->WaitOne();
FireServiceAndOrHold();
}
}
This works relatively well but I am calling this before letting the service now I am ready to accept input so it never attempts to wait for me to release the mutex for it. Before I attempt to re-order things I would like to know what is going wrong with the above function. The error I get is:
Object synchronization method was called from an unsynchronized block of code.
Because calling release on a mutex that hasn't been WaitOne'd will throw I catch that, knowing I am free to take ownership of it and continue. But I am wrong. It hangs forever on the WaitOne() statement. I know what the other process is doing all this time because it is trapped in my second debugger window. It is not touching the mutex.
UPDATE
I've attempted the reordering I first suggested, this seemed good but now I find that the mutex is only sort of Global, despite having a Global\name.
It is shared because when my GUI c'tor's it firstInstance is false, hence I attempt to take control of it.
It is not shared because when the GUI calls WaitOne() on it the GUI blocks indefinitely. Whereas the service dances straight through its call to WaitOne() without a care in the world.
I just had an idea what might be going wrong for you there:
Hint: you cannot release a mutex on behalf of the other process! The other process will have to release the mutex if it holds it:
Process 1: Process 2:
============ =============
WaitOne (locks the mutex)
// do work WaitOne (awaits the mutex)
// do more work
// done
ReleaseMutex ------> WaitOne returns from the wait _with
the mutex locked_

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