Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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 在同一对象上同步多个对象的开销_Java_Synchronized - Fatal编程技术网

Java 在同一对象上同步多个对象的开销

Java 在同一对象上同步多个对象的开销,java,synchronized,Java,Synchronized,考虑以下代码: void A() { synchronized (obj) { for (int i = 0; i < 1000; i++) { B(); } } } void B() { synchronized (obj) { // Do something } } 调用同步的开销是多少?它是否接近于只同步一个锁的开销?同步锁是可重入的,当线程已经持有锁时,获取锁是a检查它是否已

考虑以下代码:

void A() {
    synchronized (obj) {
        for (int i = 0; i < 1000; i++) {
            B();
        }
    }
}

void B() {
    synchronized (obj) {
        // Do something
    }
}
调用同步的开销是多少?它是否接近于只同步一个锁的开销?

同步锁是可重入的,当线程已经持有锁时,获取锁是a检查它是否已经持有锁的时间,b递增计数器并随后递减计数器的时间


第一个时间最长,每次增加10-50纳秒。

这个合理问题的答案取决于操作系统、硬件和特定的虚拟机实现

撇开函数调用的成本,在一个操作系统/体系结构中,几乎没有成本,考虑现代处理器/OS/VM,更多的是考虑纯软件处理器仿真。在单个绿色线程VM上,除了调用开销之外,它的成本可能接近于零。即使在ARM和Intel之间,成本也会有所不同

synchronized通常通过使用OS同步原语在VM内部实现,并使用一些启发式方法来加速常见情况。反过来,操作系统使用硬件指令和启发式方法来执行此任务。通常,后续获取已获取的同步原语在操作系统中非常有效,在典型的生产级虚拟机上非常有效

在现代的Windows/Linux虚拟机和Intel/AMD处理器上,通常情况下,假设机器处于空闲状态,它不会花费很多CPU周期,并且处于低纳秒范围内

请注意,一般来说,这是一个非常复杂的主题。涉及软件、硬件的多层以及在相同硬件资源上运行的其他任务的影响。在这里,即使是一个小的子课题的严格研究也可以组成多个博士学位。论文

不过,在实践中,我的建议是假设在小循环中进行第二次同步的成本为零,除非遇到不太可能出现的特定瓶颈

如果有大量的迭代,与单次同步相比,它肯定会增加成本,而总体效果取决于您在循环中所做的事情。通常,在每次迭代中都有一些工作使得相对开销可以忽略不计。但在某些情况下,与单次同步相比,它可能会阻止循环优化并增加大量开销,而不是作为一种实际措施。然而,在大型循环的常见实际情况下,应考虑不同的设计,并避免执行外部同步以降低成本


例如,要了解VM实现,您可以查看的同步部分。这有点过时,但很容易理解。

你说的开销是什么意思?内存消耗?运行时间?还有别的吗?我是说运行时间!它将更多,因为synchronized的调用次数是单次调用用例的1000倍。所以VM必须在obj上添加1000个额外的锁令牌。@Korashen难道它不明白它已经获得了锁吗?