Delphi库以一种强制一个声明另一个对象来存储该对象的锁定方法返回的引用的方式实现了许多线程友好对象。因此,该对象实质上封装了锁定时返回的主要对象。例如;
List := ThreadList.Unlocklist;
// do something with List
ThreadList.LockList;
为甚麽要这样做呢?为什么不鼓励从主对象继承、添加锁定对象、重写构造函数和析构函数?例如,以下实现将TMREWSync添加到列表中;
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;
发布于 2014-03-03 12:41:46
在继承时,您会陷入加载-修改-存储陷阱。
假设您希望增加对象的优先级:
int prio = myObject.getPriority();
myObject.setPriority(prio+1);
现在,考虑一下当另一个线程想降低优先级时会发生什么:
int prio = myObject.getPriority();
myObject.setPriority(prio-1);
一个交错的呼叫序列可以是:
//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
还有几个选项几乎都是坏的。
这可以通过将操作封装在一个方法中来解决,但是对于涉及多个对象的复杂操作,这很快就变得不可行了。
此外,如果对象更改,则需要修改锁子类以包含新方法。
发布于 2014-03-03 13:16:46
采取这种方法的一个无可争辩的原因是,对象有一个锁,而不是一个锁。一旦你得到了正确的答案,一切就变得简单了。
https://softwareengineering.stackexchange.com/questions/231060
复制相似问题