我只是想探讨一下ThreadSafe是什么意思?
以下是我的理解:
对我来说,它看起来像;允许多个线程同时访问一个集合;这与它的同步无关。例如,任何没有同步关键字的方法;是线程安全的,意味着多个线程可以访问它。
由开发人员选择在此方法上维护更多逻辑(同步),以便在多线程访问数据时保持数据完整性。这与线程安全是分开的。
如果我的上述陈述是错误的;只需阅读下面的 JAVA DOC for 'ConcurrentHashMap:
键集:视图的迭代器是一个“弱一致性”迭代器,它永远不会抛出ConcurrentModificationException,并保证遍历迭代器构造时存在的元素,并可能(但不保证)反映构造后的任何修改。
上面的语句说键集迭代器不会保证数据的完整性;而多线程正在修改集合。
能否请您回答我,*是KeySet迭代器的并发HashMap是线程安全的吗?
我对线程安全的理解是正确的吗??
根据您的定义,由< code > concurrent hashmap . keyset()返回的< code >集合是线程安全的。
然而,它可能以非常奇怪的方式运行,正如您在引用中所指出的那样。
Set
,条目可能会随机出现和/或消失。即。如果您在同一个对象上调用包含
两次,则两个结果可能会不同。Iterable
,您可以在两个不同的线程中开始对其底层对象进行两次迭代,并发现两次迭代枚举了不同的条目。包含
并且迭代也可能不匹配。但是,如果您在拥有< code >集合的同时,以某种方式锁定基础< code>Map以防修改,则此活动不会发生,但是需要这样做并不意味着该结构不是线程安全的。
java.util.concurrent
包背后的一般思想是提供一组数据结构,这些结构在没有强一致性的情况下提供线程安全访问。通过这种方式,这些对象实现了更高的并发性,然后正确锁定了对象。
线程安全意味着,即使没有任何显式同步,您也永远不会损坏对象。在Hashtable
和HashMap
中,一些方法是多线程访问的潜在问题,例如删除
方法,它首先检查元素是否存在,然后将其删除。这些方法在中实现为原子操作,因此您不需要担心会丢失一些数据。
然而,这并不意味着这个类在每次操作时都会被自动锁定。像< code>putAll
和迭代器这样的高级操作是不同步的。该类不提供强一致性。操作的顺序和时间安排保证不会损坏对象,但不能保证生成准确的结果。
例如,如果您在调用puAll
的同时打印对象,您可能会看到部分填充的输出。与新插入同时使用迭代器也可能不会反映您引用的所有插入。
这不同于线程安全。尽管结果可能会让您感到惊讶,但您可以放心,没有任何东西会丢失或被意外覆盖,在对象中添加和删除元素不会有任何问题。如果这种行为足以满足您的需求,建议您使用< code > Java . util . concurrent 类。如果您需要更多的一致性,那么您需要使用来自< code>java.util的同步类或者自己使用同步。
KeySet:视图的迭代器是一个“弱一致性”迭代器,它永远不会抛出并发修改异常,并保证遍历迭代器构造时存在的元素,并且可能(但不保证)反映构造后的任何修改
这本身就解释了,并发HashMap的KeySet迭代器是线程安全的。
问题内容: 在javadoc中,ConcurrentHashMap如下: 检索操作(包括get)通常不会阻塞,因此可能与更新操作(包括put和remove)重叠。检索反映了自启动以来最新完成的更新操作的结果。对于诸如putAll和clear的聚合操作,并发检索可能仅反映某些条目的插入或删除。同样,迭代器和枚举返回的元素反映了在创建迭代器/枚举时或此后某个时刻哈希表的状态。他们不抛出Concurre
HashMap的底层算法采用了链地址法来解决哈希冲突 哈希表 在数据结构中有一种称为哈希表的数据结构,它实际上是数组的推广。如果有一个数组,要最有效的查找某个元素的位置,如果存储空间足够大,那么可以对每个元素和内存中的某个地址对应起来,然后把每个元素的地址用一个数组(这个数组也称为哈希表)存储起来,然后通过数组下标就可以直接找到某个元素了。这种方法术语叫做直接寻址法。这种方法的关键是要把每个元素和
假设我有std::vector和两个线程。 第一个线程正在处理擦除函数,而第二个线程在for循环中 这种情况是线程安全的吗? 第二个线程会继续运行还是抛出异常?
问题内容: 我有一个多线程程序,在其中创建生成器函数,然后将其传递给新线程。我希望它本质上是共享/全局的,以便每个线程都可以从生成器获取下一个值。 使用这样的生成器是否安全?还是会遇到从多个线程访问共享生成器的问题/情况? 如果不是,是否有更好的方法来解决此问题?我需要可以在列表中循环并为任何线程调用它生成下一个值的东西。 问题答案: 它不是线程安全的;同时调用可能交错,并与局部变量混淆。 常用的
问题内容: 我正在制作一个需要一堆日记条目并计算总和的应用程序。 下面的方法是在有 多个线程 调用该方法时是线程/并发安全的。我想确保每个电话都能正确更新总数。 如果不安全,请说明为确保线程安全我该怎么做。 我需要获取/放置还是有更好的方法? 非常感谢! 更新: 谢谢大家的回答,我已经知道上面的代码 不是线程安全的 。 感谢Vint建议使用替代。我以前用来保存整数和,我想知道BigDecimal是
问题内容: 失败安全迭代器是那些不会失败的迭代器 。 但是和之间有什么区别? 都一样吗 问题答案: 无论和迭代器不乱扔。 依赖CAS( compare-and-swap )的集合具有弱一致性的迭代器,该迭代器反映了自创建以来对其后备集合进行的部分更改,但不一定反映所有更改。例如,如果集合中的元素在迭代器到达之前已被修改或删除,则它肯定会反映出这些更改,但对插入没有任何保证。 迭代器机制复制内部Co