在system.classes单元中,CheckSynchronize在ThreadLock上持续调用TMonitor的Exit和Enter以保护SyncList。

因为代码做的第一件事是换出SyncList,并且由于对SyncList的所有其他访问也受到ThreadLock上的TMonitor的保护,这只是不必要的代码,增加了锁争用的可能性。

TMonitor.Enter(ThreadLock);

try
Pointer(LocalSyncList) := AtomicExchange(Pointer(SyncList), Pointer(LocalSyncList));
try
Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);
if Result then
begin
while LocalSyncList.Count > 0 do
begin
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
TMonitor.Exit(ThreadLock);
try
try
if Assigned(SyncProc.SyncRec.FMethod) then
SyncProc.SyncRec.FMethod()
else if Assigned(SyncProc.SyncRec.FProcedure) then
SyncProc.SyncRec.FProcedure();
except
if not SyncProc.Queued then
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject
else if Assigned(ApplicationHandleException) then
ApplicationHandleException(SyncProc.SyncRec.FThread);
end;
finally
SyncProc.SyncRec.FThread := nil;
TMonitor.Enter(ThreadLock);
end;
if not SyncProc.Queued then
TMonitor.Pulse(SyncProc.Signal)
else
begin
Dispose(SyncProc.SyncRec);
Dispose(SyncProc);
end;
end;
end;
finally
LocalSyncList.Free;
end;
finally
TMonitor.Exit(ThreadLock);
end;
用下面代码替换:
TMonitor.Enter(ThreadLock);

try
Pointer(LocalSyncList) := AtomicExchange(Pointer(SyncList), Pointer(LocalSyncList));
finally
TMonitor.Exit(ThreadLock);
end;

try
Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);
if Result then
begin
while LocalSyncList.Count > 0 do
begin
SyncProc := LocalSyncList[0];
LocalSyncList.Delete(0);
try
try
if Assigned(SyncProc.SyncRec.FMethod) then
SyncProc.SyncRec.FMethod()
else if Assigned(SyncProc.SyncRec.FProcedure) then
SyncProc.SyncRec.FProcedure();
except
if not SyncProc.Queued then
SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject
else if Assigned(ApplicationHandleException) then
ApplicationHandleException(SyncProc.SyncRec.FThread);
end;
finally
SyncProc.SyncRec.FThread := nil;
end;
if not SyncProc.Queued then
TMonitor.Pulse(SyncProc.Signal)
else
begin
Dispose(SyncProc.SyncRec);
Dispose(SyncProc);
end;
end;
end;
finally
LocalSyncList.Free;
end;
https://quality.embarcadero.com/browse/RSP-16353

http://blog.sina.com.cn/s/blog_44fa172f0102wcsp.html

CheckSynchronize实现的不必要的复杂的更多相关文章

  1. Total Commander 8.52 Beta 1

    Total Commander 8.52 Beta 1http://www.ghisler.com/852_b1.php 10.08.15 Release Total Commander 8.52 b ...

  2. Delphi Dll 消息处理

    转载:http://blog.csdn.net/lailai186/article/details/8770643 事情的导火线是GIF图片的显示. 在应用程序中, 利用三方的GIFImage.pas ...

  3. Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……

    接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event) 事件(Event)与De ...

  4. Delphi线程基础知识

    参考http://blog.chinaunix.net/uid-10535208-id-2949323.html 一.概述 Delphi提供了好几种对象以方便进行多线程编程.多线程应用程序有以下几方面 ...

  5. Synchronization in Delphi TThread class : Synchronize, Queue

    http://embarcadero.newsgroups.archived.at/public.delphi.rtl/201112/1112035763.html > Hi,>> ...

  6. Delphi组件indy 10中IdTCPServer修正及SSL使用心得

    indy 10终于随着Delphi2005发布了,不过indy套件在我的印象中总是复杂并且BUG不断,说实话,不是看在他一整套组件的面子上,我还是喜欢VCL原生的Socket组件,简洁,清晰.Indy ...

  7. DLL ActiveForm 线程同步问题

    本文试着从分析Synchronize同步执行的实现机制入手,来解决DLL/ActiveForm中线程同步的问题. 线程中进行同步时调用的Synchronize函数,仅仅是把调用调用线程.调用方法地址. ...

  8. Dll方式的线程,需要引用这个

    {== D6DLLSynchronizer =================================================} {: This unit handles the D6 ...

  9. WM_ERASEBKGND官方解释(翻译),以及Delphi里所有的使用情况(就是绘制窗口控件背景色,并阻止进一步传递消息)

    #define WM_ERASEBKGND                   0x0014 Parameters wParam A handle to the device context. //  ...

随机推荐

  1. cordova 生成发行版apk,并添加证书 – 畅玩Coding

    原文:cordova 生成发行版apk,并添加证书 – 畅玩Coding 首先jdk生成证书. 1.进入jdk安装目录 D:\Java\jdk1.7.0\bin 2.执行命令 keytool -gen ...

  2. hbase 2.0.2 分布式安装配置/jar包替换

    环境 zk: 3.4.10 hadoop 2.7.7 jdk8 hbase 2.0.2 三台已安装配置好的hadoop002,hadoop003,hadoop004 1.上传并解压hbase-2.1. ...

  3. so文件成品评论【整理】

    这是我的 @布加迪20 AZ在一篇文章中写道:<汉化so文件的心得>中的技术附件做的简洁性整理.原来的看起来不是非常方便.一起分享学习.. 正文 SO文件汉化心得 --By布加迪20   ...

  4. Python多线程 简明例子

    综述   多线程是程序设计中的一个重要方面,尤其是在服务器Deamon程序方面.无论何种系统,线程调度的开销都比传统的进程要快得多. Python可以方便地支持多线程.可以快速创建线程.互斥锁.信号量 ...

  5. centos6.5安装apache2.x并更改默认80port

    因为现在nginx它已成为反向代理软件的主流.因此,linuxserver在系统.我们几乎总是安装nginx东方的,这使在同一时间使用apache带来了麻烦.因为apache它用于通过缺省80port ...

  6. Alamofire - 优雅的处理 Swift 中的网络操作

    网络处理,应该是我们平时开发的时候最常用到的操作.比如读取 JSON 数据,下载图片,这些操作都要和网络打交道,一个高效稳定的网络操作库对于提升我们日常的开发效率有着非常关键的作用.Alamofire ...

  7. ASP Get请求

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  8. github中README.md文件写法解析,git指令速查表

    http://blog.csdn.net/u012234115/article/details/41778701 http://blog.csdn.net/u012234115/article/det ...

  9. 数据绑定(四)使用DataContext作为Binding的Source

    原文:数据绑定(四)使用DataContext作为Binding的Source DataContext属性被定义在FrameworkElement类里,这个类是WPF控件的基类,这意味着所有WPF控件 ...

  10. CreateThread传递多个参数的方法(利用结构体的参数指针)

    很多朋友一直都在问CreateThread如何传递多个参数,CreateThread传递参数的方式是指针传递的,所以这里也可以利用指针来做!Demo 关键代码如下: type  TfrmTestThr ...