Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在java中synchronized关键字很慢?_Java_Multithreading - Fatal编程技术网

为什么在java中synchronized关键字很慢?

为什么在java中synchronized关键字很慢?,java,multithreading,Java,Multithreading,最近,我和一位朋友讨论了java中的并发性,他问我为什么synchronized关键字在一块代码或方法周围很慢。我回嘴说它很慢,因为它需要一个对象监视器。此外,它还提供了一个“先发生后保证”,它必须将缓存中的所有变量与主内存同步,并且在块结束时,它必须刷新缓存。它还可以防止编译器以及cpu对指令进行重新排序。然而,他表示,这些确实会导致经济放缓,但这并不是性能下降的主要原因。本质上,即使线程命中同步块时没有争用,它也会从用户模式切换到内核模式,线程必须保存状态,然后当它离开块时,它必须再次重新加



最近,我和一位朋友讨论了java中的并发性,他问我为什么synchronized关键字在一块代码或方法周围很慢。我回嘴说它很慢,因为它需要一个对象监视器。此外,它还提供了一个“先发生后保证”,它必须将缓存中的所有变量与主内存同步,并且在块结束时,它必须刷新缓存。它还可以防止编译器以及cpu对指令进行重新排序。然而,他表示,这些确实会导致经济放缓,但这并不是性能下降的主要原因。本质上,即使线程命中同步块时没有争用,它也会从用户模式切换到内核模式,线程必须保存状态,然后当它离开块时,它必须再次重新加载状态。我试图在网上找到描述这一点的文献,但我找不到任何文献。我想知道是否有人能证实这是正确的?为什么java线程在点击synchronized时要进入内核模式?为什么不在这之前呢?这与本文中提出的问题不同,因为我想问的是从用户模式到内核模式的显式切换,这是否会导致性能下降?

你朋友说的绝对不正确

你说得很对,同步的代价是什么。最困难的部分实际上是(特别是在x86/x86_64处理器上)比较和交换指令,它比较并设置当前线程作为锁的所有者。在x86/x86_64上,cmpxchg指令用于此操作,当它到达主内存时,它比任何常规指令都慢。然后,正如您所提到的,内存障碍会降低缓存速度

在其他一些体系结构上,尤其是基于RISC的体系结构上,通常使用被动负载独占/存储独占,这通常要快得多。因此,不同的架构可能会有所不同


无论如何,Java(和任何其他语言)都试图避免进入内核,而大多数mutext实现只有在几次重试之后,当几乎确定线程需要挂起时,才会这样做。

试着阅读这个答案。选民们没有阅读这个问题。他们只是不喜欢你暗示Java同步很慢