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

Java已同步且发生在[重复]之前

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

Java已同步且发生在[重复]之前

因为(1)和(2)在同一线程中执行,所以具有hb(1,2)和模拟hb(3,4)。在(2)中是监视器的解锁,在(3)中是同一监视器的锁定,因此hb(2,3),因此hb(1,4)和str应该等于“
newValue”。那是对的吗?

是的,您的逻辑对于此特定方案是正确的。如果(且仅当)

2
3
then 之前执行
hb(2, 3)
。要理解为什么应该这样,请想象一个如下的线程过程:

localState *= 2;synchronized(object) {    sharedState = localState;}

尽管

localState
同步块 外部 计算的,但其他线程也必须看到此计算 也必须 看到的正确值
sharedState

但是,重要的是要了解没有理由期望您所要求的订单作为结果。例如,可以很容易地以这种方式执行:

(1)T1:data.setValue(“ newValue”);(3)T2:已同步(对象){}(4)T2:字符串str = data.getValue();(2)T1:已同步(对象){}

这很不好,因为现在

T1
正在
T2
读取内存时,它正在不同步地写入内存中的某个位置。(
T2
甚至可以在写入发生的同时读取!)


要了解之前发生的一切,请想象这些线程正在同时运行(就像线程一样)并在以下时间轴上执行:

  | T1 | T2-------------------------------------------------- -----------1 | 同步(对象){} |2 | data.setValue(“ newValue”); | 字符串str = data.getValue();3 | | 同步(对象){}

注意我如何调整这些假设的动作。

  • 在位置
    1
    T1
    获取锁并将其释放。
  • 在点处
    2
    T1
    执行写操作,同时
    T2
    执行读操作。
  • 在位置
    3
    T2
    获取锁并将其释放。

实际上第一个发生 在点

2
T1
是写还是
T2
读?

同步不能保证线程实际相对于彼此执行的顺序。相反,它与线程之间的 内存一致性 有关。

在点处

2
,因为没有同步,所以即使
T1
实际上是
T2
读,
T2
也可以自由查看内存中的 值。因此,它可以 出现
T2(2)
发生过
T1(2)

从技术上讲,这意味着在同步之外,线程可以在CPU高速缓存而不是主内存中自由读取/写入。同步强制在主存储器中进行读/写。

现在有了第二个并发时间表:

  T1 | T2-------------------------------------------------- ---------- 同步(对象){| 同步(对象){  data.setValue(“ newValue”); | 字符串str = data.getValue(); } | }

尽管我们不能保证哪个线程首先获取锁,但是我们可以保证内存访问将是一致的。我们还保证他们的行动不会重叠,这在第一个时间表中是可能的。

  • 如果先
    T1
    获取锁,则可以确保
    T1
    的同步操作看起来像在
    T2
    操作之前发生。(
    T1
    肯定会在
    T2
    读之前写。)
  • 如果先
    T2
    获取锁,则可以确保
    T2
    的同步操作看起来像在
    T1
    操作之前发生。(
    T1
    肯定会在
    T2
    读取后写。)


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

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

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