当前位置: 首页 > 面试题库 >

空的synced(this){}是否对线程之间的内存可见性有任何意义?

奚正谊
2023-03-14
问题内容

我在关于StackOverflow的评论中阅读了这篇文章:

但是,如果您想安全起见,可以在@PostConstruct的末尾添加简单的synced(this){} [方法]

[请注意变量不是可变的]

我在想,只有在块中执行写入和读取操作,或者至少读取是易失性操作 时,才会 强制执行 before-beforesynchronized

引用的句子正确吗?空synchronized(this) {}块是否将当前方法中所有更改的变量刷新到“常规可见”内存中?

请考虑一些场景

  • 如果第二个线程从不调用锁this怎么办?(假设第二个线程以其他方法读取)。请记住,这个问题是关于: 刷新对其他线程的更改 ,而不是 给其他线程一种方式(同步的)来轮询原始线程所做的更改 。同样,在Spring @PostConstruct上下文中,其他方法中的不同步也很有可能-如原始评论所述。

  • 更改的内存可见性是否仅在另一个线程的第二次和后续调用中才强制执行?(请记住,此同步块是我们方法中的 最后一次 调用)-这会将这种同步方式标记为非常不好的做法(首次调用中的值过时)


问题答案:

在a之前发生的所有写操作对a monitor exit之后的所有线程可见monitor enter

一个synchronized(this){}可以变成像字节码

monitorenter
monitorexit

因此,如果在写入之前有大量写入操作,则synchronized(this){}这些写入操作将在之前发生monitorexit

这将我们带到我的第一句话的下一点。

对所有线程可见 monitor enter

因此,现在,为了使线程确保发生写操作,它必须执行相同的同步,即synchornized(this){}。这将至少发出a
monitorenter并确定您在订购之前发生的情况。

所以回答你的问题

空的synced(this){}块是否会将当前方法中更改的所有变量都刷新到“一般可见”的内存中?

是的,只要您想读取那些非易失性变量时保持相同的同步性即可。

解决您的其他问题

如果第二个线程从不调用锁怎么办?(假设第二个线程以其他方法读取)。请记住,这个问题是关于:刷新对其他线程的更改,而不是给其他线程一种方式(同步的)来轮询原始线程所做的更改。在Spring
@PostConstruct上下文中,其他方法中的不同步也很有可能

那么在这种情况下,synchronized(this)没有任何其他上下文的使用是相对无用的。没有事前发生的关系,从理论上讲,它和不包括它一样有用。

更改的内存可见性是否仅在另一个线程的第二次和后续调用中才强制执行?(请记住,此同步块是我们方法中的最后一次调用)-这会将这种同步方式标记为非常不好的做法(首次调用中的值过时)

内存可见性是由第一个调用的线程强制执行的synchronized(this),因为它将直接写入内存。现在,这并不一定意味着每个线程都需要直接从内存中读取。他们仍然可以从自己的处理器缓存中读取。进行线程调用synchronized(this)可确保它从内存中提取字段的值并检索最新的值。



 类似资料:
  • 问题内容: 我经常听到与访问线程之间的进程内存相比,访问进程之间的共享内存段不会降低性能。换句话说,多线程应用程序不会比使用共享内存的一组进程更快(不包括锁定或其他同步问题)。 但我有疑问: 1)shmat()将本地进程虚拟内存映射到共享段。必须为每个共享内存地址执行此转换,并且转换可能会花费大量成本。在多线程应用程序中,不需要额外的转换:所有VM地址都转换为物理地址,就像在不访问共享内存的常规过

  • 问题内容: 我们可以拥有任何大小的Java对象而不必担心异常吗?我将使用一个类的对象,该类由成千上万个包含s和s以及许多其他非原始类型的其他对象组成。 谢谢 问题答案: Java Heap是对您可以在系统中拥有的对象大小的限制。 如果对象的大小超出堆大小,则会生成“内存不足”错误。 在您的情况下,总对象的大小(ArrayList中的对象+系统中其他对象)的重要性更大,因为ArrayList只是引用

  • 问题内容: 当我阅读“ 实践中的Java并发性 ” c03时,我对以下程序感到困惑: 由于重新排序和线程可见性,循环可能永远不会停止,或者输出可能为零,但是我已经尝试了很多次,并且输出始终为42。所有原因是我太幸运了吗? 问题答案: 所有的原因是我太幸运了吗? 不必要。这也将取决于您的处理器体系结构和JVM实现。那就是微妙的内存模型问题的问题之一:它们很难在野外复制。

  • 编辑:更正了下面ARLCode注意到的CSS中的一个错别字-不相关。只使用CSS,我尝试动画一些文本,这样不同的文本块开始隐藏,在计时器上变得可见,然后在计时器上淡出,按顺序。 首先,我从使用隐藏的所有文本开始,并添加一个动画以在n秒后更改可见性值。 此外,我在 中嵌套了 并添加了一个动画,通过动画化不透明度来淡化 。这将在(n+x)秒后淡出刚刚出现的文本。 淡出没有问题,但弹出从来不起作用。当我

  • 问题内容: 考虑以下代码块: 当我在构造函数中初始化两个变量(和)时,其他两个变量(和)是否需要内存中的空间来存储null值? Q1。如果它们确实需要空间,那么值将占用多少内存?(例如,占用4个字节)。 Q2。字符串在内存中占用多少空间?字符串需要多少存储空间?它取决于字符串的长度吗? 问题答案: 在Java中,它只是引用(基本上是受限制的指针)可以具有的值。这意味着引用没有任何意义。在这种情况下

  • 问题内容: 我在一个具有不同进程的应用程序上工作,并被要求包含那些进程以实现更多隔离。 问题在于,进程与单个“管理程序”进程共享内存以便交换数据(它们使用经典的共享缓冲区)。该解决方案是为满足性能要求而实施的,因为它在用户空间中运行,因此在用户空间和内核空间之间没有内容切换。 如果我没看错,则不可能在单个IPC名称空间内运行多个docker容器,但是我不知道单个docker容器是否可能属于不同的I