0

Delphi RAD libraries implement many thread friendly objects in a way which forces one to declare another object for storing the reference returned by that object's locking method. The object thus essentially encapsulates the prime object which is returned on locking. For example;

List := ThreadList.Unlocklist;
// do something with List
ThreadList.LockList;

Why is this approach taken? Why is inheriting from the prime object, adding the locking object, overriding constructors and destructors, discouraged? For example the following implementation adds a TMREWSync to a list;

IMREWS = interface

  ['{5B6DE5FA-847B-42D5-8BF4-9EB20A452C54}']

  procedure BeginRead;
  function  BeginWrite: Boolean;
  procedure EndRead;
  procedure EndWrite;

end;

TThreadList = class ( TList, IMREWS )
private

  FLock : TMREWSync;

public

  constructor Create;
  destructor  Destroy; override;

  property Lock : TMREWSync read FLock implements IMREWS;

end;

constructor TThreadList.Create;
begin
  FLock := TMREWSync.Create;
  inherited;
end;

destructor TThreadList.Destroy;
begin
  inherited;
  FLock.Free;
end;

// Usage:

ThreadList.BeginWrite;
// Do something with ThreadList
ThreadList.EndWrite;
1

when inheriting you fall into the load-modify-store trap

say you want to increase an object's priority:

int prio = myObject.getPriority();
myObject.setPriority(prio+1);

now consider what happens when another thread wants to lower the priority:

int prio = myObject.getPriority();
myObject.setPriority(prio-1);

one interleaved sequence of calls could be:

//thread1         //thead2
int prio1 = myObject.getPriority();
                  int prio2 = myObject.getPriority();
myObject.setPriority(prio1+1); // now is prio+1
                  myObject.setPriority(prio2-1); now is 2 lower than expected

there are several other options which are nearly all bad

this can be solved by encapsulating the operation in a method but that quickly becomes unfeasible for complex operations involving multiple objects

plus if the object changes you need to modify the locking subclass to include the new methods

  • Sorry, I couldn't understand your answer at all :(... How is your example act differently when using the Delphi's native approach as the object being changed is after all the same? What happens with 'complex operations involving multiple objects'? What do you mean by object changes, any examples? – Umair Ahmed Mar 3 '14 at 13:07
1

One inarguable reason for taking that approach is because an object has a lock as opposed to is a lock. As soon you get is a / has a correct, everything gets simpler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.