线程安全是否意味着没有比赛条件



ConcurrentHashMap是线程安全的,但可能会出现争用条件,因为据我所知,只有部分映射被锁定,并且只用于写操作,这意味着如果同时有读操作,就会出现争用情况。

但我也喜欢这里https://en.wikipedia.org/wiki/Thread_safety

Thread safe: Implementation is guaranteed to be free of race conditions when accessed by multiple threads simultaneously.

我可以说ConcurrentHashMap是线程安全的,但不是完全同步的吗?这里的正确术语是什么?

我不知道是否有"线程安全"的正式定义

当人们说某些是线程安全的时,他们通常意味着多个线程并发使用类方法不会导致读过类文档的合理程序员感到惊讶的行为。

Map的"线程安全"意味着:

  • 如果两个或多个线程存储不同的密钥,则所有存储都将发生
  • 如果两个或多个线程为同一个键存储不同的值,则至少会发生其中一个存储
  • 如果一个线程存储某个键的值,而另一个线程尝试获取该键的值时,则读取线程将获取旧值或新值
  • 密钥K的值永远不会因为多个线程访问和/或存储其他密钥而改变
  • 多个线程并发使用同一映射永远不会导致JVM抛出VirtualMachineError,或者导致它segfault
  • 等等

请注意,上面的一些例子是类本身无力阻止的种族条件。"线程安全"是而不是一个承诺,即如果您使用线程安全类,您的程序将不受竞争条件的影响。它只承诺类自己的源代码不会导致程序中出现与线程相关的错误。

TL;DR

"线程安全";可能取决于主观解释,而";竞赛条件";更加客观和抽象。

说明:

例如,在C++中,"cout"在其自身的实现级别上是线程安全的。当从多个线程并行调用"cout"时,你不会看到你的应用程序崩溃或向单个控制台(共享资源)输出乱码。然而,如果您使用cout从并行线程输出文本字符串,那么在某一点上,您将看到您的文本在字符序列级别上混乱不堪,因为毫无疑问存在竞争条件。

这是否意味着cout不是线程安全的?我倾向于";否";因为C++标准说它足够线程安全(我稍后再谈)。

这是否意味着你的代码不是线程安全的?这取决于情况。

如果输出混合的文本片段是您和代码用户所期望的,那么从用户的角度来看,代码可以被认为是线程安全的,尽管它有竞争条件(访问共享资源控制台,而不同步)。

但是,如果有人抱怨,而您不得不重写代码,那么这意味着它被认为不够线程安全。

因此,";不线程安全";可以松散地定义为";由于比赛条件而导致不希望的行为";。

如果没有因为种族条件而出现不受欢迎的行为,那么这可能取决于主观解释。我想说,从用户的角度来看,代码可能仍然被认为是线程安全的,尽管从技术上讲,这并不是因为它忽略了竞争条件。

返回控制台输出主题。在里面NET中,微软似乎认为C++的控制台输出不够线程安全(再次强调主观解释),所以他们以不同的方式实现了它,您可以将整个字符串输出到Console.Write,而无需混合来自不同线程的文本。

引用微软关于他们的。NET控制台:

使用这些流的I/O操作是同步的,这意味着多个线程可以从流中读取或写入流。

并且引用C++标准:

对同步(§27.5.3.4)标准iostream的并发访问对象的格式化和非格式化输入(§27.7.2.1)和输出(§27.7.3.1)函数或多线程的标准C流不会导致数据竞赛(§1.10)。[注意:用户必须仍然同步多个对象对这些对象和流的并发使用线程,如果他们希望避免交错字符。]

因此,C++认为cout足够线程安全,尽管它具有可能导致交错字符的逻辑竞争条件。相比之下,微软认为它对他们的目的来说不够线程安全,并增加了针对这种竞争条件的保护。

所以这就是为什么我认为";线程安全";主观的和上下文相关的,而种族条件是可以更客观地确定的,以决定你是否想处理它。

我认为是的,线程安全意味着不存在数据竞争的可能性。

因为线程安全意味着:;如果数据类型或静态方法在从多个线程使用时行为正确,则该方法是线程安全的,无论这些线程是如何执行的,并且不需要调用代码进行额外的协调"(麻省理工学院,软件构建课程)

争用条件基本上是线程安全代码中所说的不会发生的情况:;竞赛条件是当事件的时间或顺序影响程序的正确性时出现的一个缺陷";。(犹他大学雷格尔)

但可能会出现竞争条件,因为(snip)

因为任何"线程安全"原语的非平凡使用,甚至是互斥,都涉及到竞争,根据定义。

如果没有访问资源的竞争,您甚至不会担心"线程安全",因为访问将是连续的

当多个访问者同时更新或修改实体时,会出现竞争条件。对于单纯的读取,不存在竞争条件,因为读取与更新或修改不同。


ConcurrentHashMap是线程安全的,这意味着这个DS中可能发生竞争条件的方面已经得到了处理。

因此。。。是的,尽管不是ConcurrentHashMap中的所有方法都受到并发访问的保护,但ConcurrentHashMap是线程安全的,因为对于这些方法来说,并发访问是不成问题的。

最新更新