多线程 – 通用Threadsafe属性

前端之家收集整理的这篇文章主要介绍了多线程 – 通用Threadsafe属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我创建了这个“threadsafe”通用属性,我可以在主线程和后台线程之间使用.我做到这一点,因为我厌倦了为所有的属性和变量创建Lock对象.
  1. TLockedProp<MyType> = class
  2. private
  3. FMyProp:MyType;
  4. PropLock:TObject;
  5. procedure SetMyProp(const Value: MyType);
  6. function GetMyProp: MyType;
  7. published
  8. property Value:MyType read GetMyProp write SetMyProp;
  9. public
  10. Constructor Create;
  11. Destructor Destroy;override;
  12. end;
  13.  
  14. { TLockedProp<MyType> }
  15.  
  16. constructor TLockedProp<MyType>.Create;
  17. begin
  18. inherited;
  19. PropLock:=TObject.create
  20. end;
  21.  
  22. destructor TLockedProp<MyType>.Destroy;
  23. begin
  24. PropLock.Free;
  25. inherited;
  26. end;
  27.  
  28. function TLockedProp<MyType>.GetMyProp: MyType;
  29. begin
  30. TMonitor.Enter(PropLock);
  31. result := FMyProp;
  32. TMonitor.Exit(PropLock);
  33. end;
  34.  
  35. procedure TLockedProp<MyType>.SetMyProp(const Value: MyType);
  36. begin
  37. TMonitor.Enter(PropLock);
  38. FMyProp := Value;
  39. TMonitor.Exit(PropLock);
  40. end;

有什么问题我俯瞰吗?
这是使用这个属性类的一些代码.告诉我你的想法.

  1. TBgThread=class(TThread)
  2. private
  3. FPaused: TLockedProp<boolean>;
  4. FCount:TLockedProp<integer>;
  5.  
  6. procedure ChangeCount(pPlusMin:integer);
  7. function GetPaused:boolean;
  8. function GetCount:integer;
  9. public
  10. constructor Create;
  11. destructor Destroy;override;
  12. {Toggle Pause}
  13. procedure PausePlay;
  14. protected
  15. procedure Execute;override;
  16. published
  17. Property Paused:boolean read GetPaused;
  18. Property Count:integer read GetCount;
  19. end;
  20. constructor TBgThread.Create();
  21. begin
  22. inherited Create(true);;
  23. FPaused:=TLockedProp<boolean>.create;
  24. FPaused.Value:=false;
  25. FCount:=TLockedProp<integer>.create;
  26. FCount.Value:=0;
  27. end;
  28. destructor TBgThread.Destroy;
  29. begin
  30. FPaused.Free;
  31. FCount.free;
  32. inherited;
  33. end;
  34. procedure TBgThread.Execute;
  35. begin
  36. inherited;
  37. Repeat
  38. if not Paused then begin
  39. Try
  40. //do something
  41. finally
  42. ChangeCount(+1);
  43. end;
  44. end else
  45. Sleep(90);
  46. Until Terminated;
  47. end;
  48.  
  49. function TBgThread.GetCount: integer;
  50. begin
  51. Result:=FCount.Value;
  52. end;
  53.  
  54. procedure TBgThread.ChangeCount(pPlusMin: integer);
  55. begin
  56. FCount.Value:=FCount.Value+pPlusMin;
  57. end;
  58.  
  59. function TBgThread.GetPaused: boolean;
  60. begin
  61. result := FPaused.Value;
  62. end;
  63.  
  64. procedure TBgThread.PausePlay;
  65. begin
  66. FPaused.Value:=not FPaused.Value;
  67. end;

解决方法

你的代码很好,并且将序列化对该属性的读/写访问.我唯一的注释是,您不需要创建一个单独的锁定对象.您可以删除PropLock并锁定Self.

我的代码库中有几乎相同的类.唯一的区别是:

>我使用关键部分而不是TMonitor,因为我仍然不信任TMonitor.早期的版本有一些错误,并且暗示了我的信心.不过,我怀疑现在TMonitor代码很可能是正确的.所以我看不到你改变的理由.
>我使用try / finally与锁定和解锁的代码.这可能对我来说有点悲观,因为很难看到你如何从getter和setter方法中的异常中有效地恢复.假设我的习惯.

FWIW,我的班级看起来像这样:

  1. type
  2. TThreadsafe<T> = class
  3. private
  4. FLock: TCriticalSection;
  5. FValue: T;
  6. function GetValue: T;
  7. procedure SetValue(const NewValue: T);
  8. public
  9. constructor Create;
  10. destructor Destroy; override;
  11. property Value: T read GetValue write SetValue;
  12. end;
  13.  
  14. { TThreadsafe<T> }
  15.  
  16. constructor TThreadsafe<T>.Create;
  17. begin
  18. inherited;
  19. FLock := TCriticalSection.Create;
  20. end;
  21.  
  22. destructor TThreadsafe<T>.Destroy;
  23. begin
  24. FLock.Free;
  25. inherited;
  26. end;
  27.  
  28. function TThreadsafe<T>.GetValue: T;
  29. begin
  30. FLock.Acquire;
  31. Try
  32. Result := FValue;
  33. Finally
  34. FLock.Release;
  35. End;
  36. end;
  37.  
  38. procedure TThreadsafe<T>.SetValue(const NewValue: T);
  39. begin
  40. FLock.Acquire;
  41. Try
  42. FValue := NewValue;
  43. Finally
  44. FLock.Release;
  45. End;
  46. end;

我想真的只有一种方法来写这个课程!

猜你在找的Java相关文章