java meomry 模型要求synchronize
在同一监视器上同步的块对在这些块中修改的变量强制执行前后处理。例子:
// in thread A
synchronized( lock )
{
x = true;
}
// in thread B
synchronized( lock )
{
System.out.println( x );
}
x==true
在这种情况下,只要线程 A 已经通过了该块,线程 B 就会看到synchronized
。现在我正在重写大量代码以使用更灵活(据说更快)的锁java.util.concurrent
,尤其是ReentrantReadWriteLock
. 所以这个例子看起来像这样:
编辑:该示例已损坏,因为我错误地转换了代码,如matt b所述。固定如下:
// in thread A
lock.writeLock().lock();
{
x = true;
}
lock.writeLock().unlock();
// in thread B
lock.readLock().lock();
{
System.out.println( x );
}
lock.readLock().unlock();
但是,我没有在内存模型规范中看到任何暗示这种锁也暗示着必要的排序。研究实现它似乎依赖于对内部 volatile 变量的访问AbstractQueuedSynchronizer
(至少对于 sun 实现)。然而,这不是任何规范的一部分,而且对非易失性变量的访问并没有真正考虑由这些变量给出的内存屏障覆盖,是吗?
所以,这是我的问题:
synchronized
假设与“旧”块相同的顺序是否安全?- 这是在某处记录的吗?
- 访问任何 volatile 变量是否是任何其他变量的内存屏障?
问候, 史蒂芬
--
对亚纳蒙的评论:
看下面的代码:
// in thread a
x = 1;
synchronized ( a ) { y = 2; }
z = 3;
// in thread b
System.out.println( x );
synchronized ( a ) { System.out.println( y ); }
System.out.println( z );
据我了解,内存屏障强制第二个输出显示 2,但对其他变量没有保证影响......?那么这如何与访问 volatile 变量相比呢?