栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java中的+ =运算符是线程安全的吗?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中的+ =运算符是线程安全的吗?

否。该

+=
操作不是线程安全的。对于涉及分配给共享字段或数组元素的任何表达式,它要求锁定和/或适当的“先于”关系链是线程安全的。

(在字段声明为

volatile
的情况下,“先发生”关系存在…但是仅在读和写操作上存在。该
+=
操作由一个读和一个写操作组成。它们分别是原子的,但是顺序不是。大多数使用的赋值表达式
=
涉及一个或多个读取(在右侧)和写入。该
序列 也不是原子的。)

有关完整的故事,请阅读JLS
17.4
…或Brian Goetz等人的“ Java Concurrency in Action”的相关章节。

据我所知,基本类型的基本操作是线程安全的。

实际上,这是一个不正确的前提:

  • 考虑数组的情况
  • 考虑到表达式通常由一系列操作组成,并且不能保证一系列原子操作是原子操作。

double
类型还有另一个问题。JLS(17.7)说:

“就Java编程语言内存模型而言,对非易失性long或double值的单次写入被视为两次单独的写入:一次写入每个32位的一半。这可能导致线程看到以下情况:来自一次写入的64位值的前32位,以及来自另一次写入的后32位。”

“易失的long和double值的写入和读取始终是原子的。”


在评论中,您询问:

那么我应该使用哪种类型来避免全局同步,这会停止此循环内的所有线程?

在这种情况下(如果您要更新

double[]
,则无法使用锁或原始互斥锁进行同步。

如果您使用

int[]
long[]
,则可以用
AtomicIntegerArray
或替换它们,
AtomicLongArray
并利用这些类的无锁更新。但是,没有
AtomicDoubleArray
课程,甚至没有
AtomicDouble
课程。

UPDATE -有人指出,番石榴提供了一个

AtomicDoubleArray
类,这样 是一种选择一个好的实际。)

避免“全局锁定”和大量争用问题的一种方法可能是将数组划分为概念区域,每个区域都有自己的锁定。这样,一个线程仅在使用数组的同一区域时才需要阻塞另一个线程。(如果绝大多数访问是读取的,那么单作家/多读者锁定也可能会有所帮助。)



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/595376.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号