加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

多线程 – 枚举类型 – 线程安全

发布时间:2020-12-15 04:49:30 所属栏目:Java 来源:网络整理
导读:我和同事争论枚举类型的线程安全性.具有以下简单枚举类型: type Suit = (Club,Diamond,Heart,Spade); 并在类中声明为变量,如下面的虚拟代码: type TTest = classprivate FSuit: Suit; function SetSuit(aValue: Suit);public property GimmeSuit: Suit rea
我和同事争论枚举类型的线程安全性.具有以下简单枚举类型:

type Suit = (Club,Diamond,Heart,Spade);

并在类中声明为变量,如下面的虚拟代码:

type 
TTest = class
private 
  FSuit: Suit;
  function SetSuit(aValue: Suit);
public
  property GimmeSuit: Suit read FSuit;

.....

function SetSuit(aValue: Suit);
begin
  FSuit:= aValue;
end;

我说这段代码是线程安全的,因为设置FSuit变量的值是一个原子操作.我错了?关于这个案子我没有在网上找到任何东西.

解决方法

在使用术语之前,需要澄清您使用的术语,线程安全和原子,才能正确解决.

> Threadsafe是一个模糊的术语,必须根据其应用的具体环境进行限定. Eric Lippert的经典文章What is this thing you call “thread safe”?详细介绍了这一点
>原子操作是不可分割的操作.系统的其他部分似乎同时发生.

在您显示的代码中,我假设多个线程都在读取和写入FSuit.

有了这一切,读取和写入FSuit就是原子的,只要它是单个字节或对齐.

单字节内存访问始终是原子的.如果枚举类型大于单个字节,则必须将内存读/写对齐为原子.未对齐的内存访问可能会撕裂.也就是说,读取线程可能只看到写入的一部分,因为该变量跨越了高速缓存行.写入线程必须将变量的一部分写入一个高速缓存行,然后将其余部分写入相邻的高速缓存行,并且读取线程可以通过两阶段写入过程部分地读取整个变量.

现在,使用默认设置,此枚举类型将是单个字节,并且类布局将对齐.因此,即使对较大的枚举类型进行读/写也是原子的.

至于你的程序是否是线程安全的,这不能从这里的信息确定.你需要澄清意图是什么.例如,假设两个线程写入FSuit,第三个线程从中读取.如果程序的正确性不依赖于那些内存访问的顺序,那么它就是线程安全的.如果它的正确性取决于排序,则它不是线程安全的并且需要同步.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读