Implementing lock based on status - multithreading

If I have a method like this:
public class Main()
{
public void Start()
{
if(//Check if another thread already invoked this method and its in processing//)
DoSomething();
}
void DoSomething()
{
//Some code in here
}
}
How to use lock to Check if a thread is already executing DoSomething() then skip it ?
I know lock will make other calls wait, But I want to skip rather than wait and execute.

You can use
tryLock
boolean tryLock()
Acquires the lock only if it is free at the time of invocation.
Acquires the lock if it is available and returns immediately with the value true. If the lock is not available then this method will return immediately with the value false.
A typical usage idiom for this method would be:
Lock lock = ...;
if (lock.tryLock()) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}
This usage ensures that the lock is unlocked if it was acquired, and doesn't try to unlock if the lock was not acquired.
Returns:
true if the lock was acquired and false otherwise

Related

check asynchronous threads state in java

I have method in class MyClassB which is triggered asynchronously from a method of MyClassA:
public void getProductCall()
{
new Thread(new Runnable() {
#Override
public void run() {
try {
productRequest = service.createS4ProductRequest(getRepriceItems());
//Below is a rest call to another system
String response = pricing.getS4ProductResponse(quote.getAssetQuoteNrAndVrsn(), productRequest);
//I'm using the below 2 lines to check from ClassA's method to see if this process has ended
setProductResponse(response);
productPriceProcessEnded=true;
} catch (Exception e) {
productPriceErrorOccured=true;
e.printStackTrace();
}
}
}).start();
}
This is the piece of code in MyClassA i used to check if the above method is complete.
for(int i=0;i<1000000000;i++)
{
if(!networkAsynCalls.isListPriceErrorOccured())
{
if(networkAsynCalls.isListPriceprocessEnded())
{
return networkAsynCalls.getListReponse();
}
else
{
Thread.sleep(250);
continue;
}
}
else
return null;
}
instead of using this random for loop can i use some inbuilt method or service pool or something ?
Because,
1) This thread on method is in another class
2) In class MyClassB i have few more methods like this, so i need to check the status of all the methods in MyClassA
Thanks for any help.
If I undestand what you're trying to do is dispatch some code to be ran asynchronously, then be able to wait until it is completed (successfully or failed). If that's the case, you should take a look at Futures.
Here is an example based on the Javadoc:
FutureTask<String> future =
new FutureTask<String>(new Callable<String>() {
public String call() {
// do stuff
return "result";
}});
This code creates an object "future" that can be invoked to execute searcher.search(target). At this point, the code is not executed at all. You simply have an object representing a computation that may be executed asynchronously. To do so, you'd call:
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(future);
This snippet created an Executor (which is a fixed pool of 5 threads), then handed over the future to it for execution. The executor will run the computation from Future asynchronously.
Future offers some methods (see the Javadoc) to wait until completion, cancel, check completion status, etc. For example,
String result = future.get();
will block, waiting for the result indefinitely. A get(10, TimeUnit.SECONDS) will wait for 10 seconds and if the future has not completed, throw.

Qt Blocking thread until condition met

class Driver : Public QObject
{
Q_OBJECT
private:
// method command: sends a command
// signal ok: command executed, sends back a message
MyDevice *device;
public:
Deriver()
{
device = new MyDevice(0);
connect (mydevice,&MyDevice::ok,this,&Driver::onInitOk);
}
public slots:
void init()
{
device->command("init");
//at this point, I want to block this method until the device signals ok with a given msg
}
command()
{
device->command("setmode x");
device->command("cmd");
//at this point, I want to block this method until the device signals ok with a given msg
}
void onInitOk(QString msg)
{
//somehow unblock the actually running command, if the msg matches
}
}
I would like to use the command/init with a QueuedConnection, so they are executed async from the gui thread, and sequentially. (Am I right?)
How can I implement the blocking effectively?
Okay so I've edited based on the clarity of the comments given. The best place to look at would be the Qt Threading Guide. This can give a much better breakdown on the systems used for concurrency.
For your example I've added a QMutex object to your Driver class. It may be worth thinking about if you want to move the thread-based controls into the MyDevice class itself if you have access.
Driver()
{
moveToThread(new QThread());
device = new MyDevice(0);
}
void init()
{
mutex.lock();
const QString& result = device->command("init");
onInitOk(result);
}
void command()
{
mutex.lock();
device->command("setmode x");
const QString& result = device->command("cmd");
onInitOk(result);
}
void onInitOk(QString msg)
{
...[STUFF]
// Even when things go wrong you MUST unlock the mutex at some point.
// You can't keep the thread blocked forever in cases of poor results.
// As such it might be better practice to unlock in
// the same function that locks!
mutex.unlock();
}
QMutex mutex;
Bear in mind I am assuming you are wanting to access the functionality from the slots mechanism. Hence why we use the moveToThead() function. When the object is accessed via slots in the GUI thread it'll now run the function on a different thread.
Likewise the mutex only blocks for all the objects that share that one mutex instance. So depending on your implementation you may have to think about what is right for you in exposing that mutex.

Simplifying VCL thread wrapper code

I am using thread wrapper which checks if function which updates VCL (which also has some arguments) was called from main thread or not and then executes in within the context of Main thread always.
It works but I want to make it simpler. The problem is that I have to repeat this code in every function which needs VCL synchronization which is prone to errors. Is there a way to make this wrapper simpler and more re-useable? Note that this particular wrapper only uses one parameter but there can be any number of parameters which are copied to TLocalArgs and passed on.
Current code:
boost::scoped_ptr<TIdThreadComponent> WorkerThread;
...
void TForm1::SetMemoMessage(UnicodeString Msg)
{
// Check which thread called function, main thread or worker thread
if (GetCurrentThreadId() != System::MainThreadID)
{
struct TLocalArgs
{
TForm1 *Form;
UnicodeString Msg;
void __fastcall SetMemoMessage() // Same name as main function to make it easier to maintain
{
// We are in main thread now, safe to call message update directly
Form->SetMemoMessage(Msg);
}
};
// We are in worker thread, wrap into Synchronize
TLocalArgs Args = { this, Msg };
WorkerThread->Synchronize(&Args.SetMemoMessage);
return;
}
// MAIN THREAD CODE is very simple compared to wrapper above
Memo1->Text = Msg;
}
TThread::Synchronize() checks MainThreadID internally for you and calls the specified procedure directly if Synchronize() is called from the main thread. So just call Synchronize() unconditionally and let it handle the details. Synchronize() also has overloaded static versions available so you don't even need a TThread pointer to call it.
Try this:
void TForm1::SetMemoMessage(UnicodeString Msg)
{
struct TLocalArgs
{
UnicodeString Msg;
void __fastcall SetMemoMessage()
{
Form1->Memo1->Text = Msg;
}
};
TLocalArgs Args;
Args.Msg = Msg;
TThread::Synchronize(NULL, &Args.SetMemoMessage);
}

c#: how terminate a background thread in dispose() method?

I have a program which runs a thread. The thread performs processing all the time and it uses some synchronized queue.
The class snapshot is as follows:
public class MyClass:IDisposable
{
private Thread myThread = new Thread(threadFunc);
private volatile bool runThread = true;
public MyClass()
{
myThread.Start();
}
public Dispose()
{
runThread = false;
}
private void threadFunc()
{
try
{
while(runThread){
queue.Take(); //This method blocks the thread if queue is empty. It uses Monitor class
//do some processing
}
}
catch(Exception e){...}
}
private void otherFunc()
{
queue.enqueue(...);//this method is executed by main thread and uses lock while adding element to the queue.
}
}
When I call Dispose() method, the thread exists threadFunc() method, but after a sec I get an execption from this func "Unable to avaluate expression...", as if the tread was terminated while doing some work. Maybe it has just released from queue.Take() blocking and has no context to run. I know I'm missing something...
How can I solve such problem and terminate the thread from the Dispose method.
Many thanks!!!
Use the overload of Take that accepts a CancellationToken. You can get a reference to a token by using the CancellationTokenSource which also has the Cancel method that you can call from Dispose to unblock the Take method. You can read more cancellation here.
Use the poison pill approach: See this thread

Do C# 4.0 BCL SpinLock's spin/block when they can't get a lock?

Given the following code:
...
private static SpinLock logLock = new SpinLock(false);
...
private static void ThreadFunc()
{
bool lockTaken = false;
logLock.Enter(ref lockTaken)
{
try
{
// do stuff with during an acquired SpinLock
}
finally
{
logLock.Exit();
}
}
}
If the Enter block "fails" because it receives a false on the lock being acquired, does the current thread spin like a spinlock and wait until it can acquire it or is this block simply bypassed and that thread loses out ?
Thanks,
Scott
A SpinLock by definition causes the thread to spin while waiting to acquire for a lock rather than blocking. Enter does not "fail" if it can't acquire the lock, it just waits.
The only case where Enter may fail throwing an exception is when thread ownership is activated, using either new SpinLock() or new SpinLock(true). In this case an exception is thrown when a thread tries to acquire a lock it already owns. In your case this can never happen because you created the lock with tracking disabled (SpinLock(false)). If the thread tries to re-acquire the lock it will simply deadlock.
This is described in the documentation of the SpinLock.Enter method.
A SpinLock is basically just a loop around trying to set a variable to a specific value.
You could consider its implementation as follows:
public struct SpinLock
{
private volatile bool _Locked;
public void Acquire()
{
while (_Locked)
;
_Locked = true;
}
public void Release()
{
_Locked = false;
}
}
(of course, the above code is not thread-safe, and I know that's not the signature of the methods of the class, it's just a pseudo-code variant to show what it is doing)
So yes, if the SpinLock is already in a locked state, attempting to acquire it will spin until it becomes available.
Also, note that by default (as in your example), the struct does not keep track of who owns the lock. This means that if a thread tries to acquire the lock twice, it will deadlock with itself on the second attempt.
The purpose of SpinLock is to be a user-level lock with little overhead. It does not add GC pressure, nor does it allocate any kernel synchronization object, it's just a struct with a few fields.

Resources