Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Accessing TObject instance when it is locked by TMonitor.Enter in the calling thread

What will happen if a thread tries to access the same object locked by another thread? I know it can be handled by TMonitor.Wait(), but what if there is no handling codes to check if it is locked? Will there be an error?

In the example below, Thread1Process locks the object and Thread2Process attempts to assign a value to the object’s property. Will the Thread2Process automatically wait before Thread1Process releases the lock to execute the next line var x: Integer := 1; or will it stop and throw an exception?

procedure Thread1Process(const AObject: TObjectDescendant);
begin
  TMonitor.Enter(AObject);
  try
    // lengthy process here...
  finally
    TMonitor.Exit(AObject);
  end;
end;

procedure Thread2Process(const AObject: TObjectDescendant);
begin
  AObject.StringProperty := 'Any value';
  var x: Integer := 1;
end;

We are using Delphi 11 Alexandria.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

TMonitor is just a synchronization lock, nothing more. Much like TMutex, TSemaphore, etc.

It doesn’t do anything to the object itself. If one thread decides to enter the lock, and a second thread doesn’t, the second thread will not be blocked in any way, and no exception will be raised 1, but there is no guarantee to the stability of the object or its members, due to lack of proper synchronization from cooperation between all threads that are using the object.

1: unless the object itself decides to raise an exception, or a system exception is raised, like from accessing invalid memory, etc.


On a side note, your call to TMonitor.Enter() needs to be outside the try block, eg:

procedure Thread1Process(const AObject: TObjectDescendant);
begin
  TMonitor.Enter(AObject);
  try
    // lengthy process here...
  finally
    TMonitor.Exit(AObject);
  end;
end;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading