微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

多线程 – 通用Threadsafe属性

我创建了这个“threadsafe”通用属性,我可以在主线程和后台线程之间使用.我做到这一点,因为我厌倦了为所有的属性和变量创建Lock对象.
TLockedProp<MyType> = class
private
  FMyProp:MyType;
  PropLock:TObject;
  procedure SetMyProp(const Value: MyType);
  function GetMyProp: MyType;
published
  property Value:MyType read GetMyProp write SetMyProp;
public
  Constructor Create;
  Destructor Destroy;override;
end;

{ TLockedProp<MyType> }

constructor TLockedProp<MyType>.Create;
begin
  inherited;
  PropLock:=TObject.create
end;

destructor TLockedProp<MyType>.Destroy;
begin
  PropLock.Free;
  inherited;
end;

function TLockedProp<MyType>.GetMyProp: MyType;
begin
  TMonitor.Enter(PropLock);
  result := FMyProp;
  TMonitor.Exit(PropLock);
end;

procedure TLockedProp<MyType>.SetMyProp(const Value: MyType);
begin
  TMonitor.Enter(PropLock);
  FMyProp := Value;
  TMonitor.Exit(PropLock);
end;

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

TBgThread=class(TThread)
  private     
    FPaused: TLockedProp<boolean>;
    FCount:TLockedProp<integer>;

    procedure ChangeCount(pPlusMin:integer);
    function  GetPaused:boolean;
    function  GetCount:integer;
  public   
    constructor Create;
    destructor  Destroy;override;
    {Toggle Pause}
    procedure PausePlay;
  protected
    procedure Execute;override;
  published
    Property  Paused:boolean read GetPaused;
    Property  Count:integer read GetCount;
  end;
constructor TBgThread.Create();
begin
  inherited Create(true);;
  FPaused:=TLockedProp<boolean>.create;
  FPaused.Value:=false;     
  FCount:=TLockedProp<integer>.create;
  FCount.Value:=0;
end;
destructor TBgThread.Destroy;
begin
  FPaused.Free;
  FCount.free;     
  inherited;
end;
procedure TBgThread.Execute;
begin
  inherited; 
  Repeat
    if not Paused then begin
        Try
          //do something
        finally
          ChangeCount(+1);
        end;
    end else
      Sleep(90);
  Until Terminated;
end;

function TBgThread.GetCount: integer;
begin
  Result:=FCount.Value;
end;

procedure TBgThread.ChangeCount(pPlusMin: integer);
begin
  FCount.Value:=FCount.Value+pPlusMin;
end;

function TBgThread.GetPaused: boolean;
begin
  result := FPaused.Value;
end;

procedure TBgThread.PausePlay;
begin
  FPaused.Value:=not FPaused.Value;
end;

解决方法

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

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

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

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

type
  TThreadsafe<T> = class
  private
    FLock: TCriticalSection;
    FValue: T;
    function GetValue: T;
    procedure SetValue(const NewValue: T);
  public
    constructor Create;
    destructor Destroy; override;
    property Value: T read GetValue write SetValue;
  end;

{ TThreadsafe<T> }

constructor TThreadsafe<T>.Create;
begin
  inherited;
  FLock := TCriticalSection.Create;
end;

destructor TThreadsafe<T>.Destroy;
begin
  FLock.Free;
  inherited;
end;

function TThreadsafe<T>.GetValue: T;
begin
  FLock.Acquire;
  Try
    Result := FValue;
  Finally
    FLock.Release;
  End;
end;

procedure TThreadsafe<T>.SetValue(const NewValue: T);
begin
  FLock.Acquire;
  Try
    FValue := NewValue;
  Finally
    FLock.Release;
  End;
end;

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1.Linux实时查看Java接口数据的方法 在Linux系统中实时查看Java接口数据通常涉及几个步骤: (1)编写Java应用程序:首先,我们需要有一个Java应用程序,它暴露了一个或多个HTTP接口。这些接口应该返回我们想要实时查看的数据。 (2)使用HTTP工具或库:在Linux上,我们可以
应用场景 C端用户提交工单、工单创建完成之后、会发布一条工单创建完成的消息事件(异步消息)、MQ消费者收到消息之后、会通知各处理器处理该消息、各处理器处理完后都会发布一条将该工单写入搜索引擎的消息、最终该工单出现在搜索引擎、被工单处理人检索和处理。 事故异常体现 1、异常体现 从工单的流转记录发现、
线程类,设置有一个公共资源 package cn.org.chris.concurrent; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @Descrip
Java中的数字(带有0前缀和字符串)
在Java 9中使用JLink的目的是什么?
Java Stream API Filter(过滤器)
在Java中找到正数和负数数组元素的数量
Java 9中JShell中的不同启动脚本是什么?
使用Java的位填充错误检测技术
java中string是什么