java当使用synchronized时,寄存器刷新是如何工作的?
我从«Java性能»一书中读到,在一台有许多寄存器的机器上运行以下代码会花费惊人的时间:
Vector v = initVector();
for (int i = 0; i < v.size(); i++) {
process(v.get(i));
}
因为Vector类的get()和size()方法是同步的,而且所有这些调用所需的寄存器刷新(到主存)是一个巨大的性能问题
避免这种情况的一种方法是在同步块中封装大量连续的细粒度同步调用,如下所示:
Vector v = initVector();
synchronized (v) {
for (int i = 0; i < v.size(); i++) {
process(v.get(i));
}
}
我有以下问题:
- 为什么即使size()和get()方法不更改寄存器中变量的值,寄存器刷新也很昂贵?在我看来,没有什么东西可以回到主内存。我错了吗李>
- 作者提出的解决方案是否意味着,一旦几个内部连续同步的方法被包装在一个外部同步调用中,内部方法就不再进行寄存器刷新,并且在外部级别只会有一个最终寄存器刷新李>
谢谢大家!
# 1 楼答案
只读方法仍然需要获取锁,否则另一个线程将能够在您读取时进行更改,从而导致随机行为
作者建议的解决方案在循环开始之前只获取一次锁,并在循环结束时释放锁。这样,如果必须在循环的每一步都获取锁,就可以跳过许多锁定/释放周期