java meomry模型要求在同一监视器上同步的synchronize块对在这些块中修改的变量执行预实现。示例:
// in thread A
synchronized( lock )
{
x = true;
}
// in thread B
synchronized( lock )
{
System.out.println( x );
}在这种情况下,只要线程A已经传递了x==true -block,线程B就会看到该线程。现在,我正在重写大量代码,以便在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();但是,我还没有在内存模型规范中看到任何提示,表明这样的锁也意味着必要的排序。从实现的角度来看,它似乎依赖于对AbstractQueuedSynchronizer内部易失性变量的访问(至少对于sun实现来说是这样)。然而,这并不是任何规范的一部分,而且对非易失性变量的访问也没有被这些变量的内存屏障所覆盖,是吗?
下面是我的问题:
synchronized块相同的顺序安全吗?你好,斯特芬
--
对Yanamon的评论:
请查看以下代码:
// 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,但对其他变量没有保证影响.?那么,这如何与访问易失变量相比较呢?
发布于 2010-04-05 00:43:53
来自API-doc
所有锁实现都必须强制执行内置监视器锁提供的相同的内存同步语义,如Java语言规范第三版(17.4内存模型)所述: *成功的锁操作与成功的锁定操作具有相同的内存同步效果。*成功的解锁操作与成功的解锁操作具有相同的内存同步效果。 不成功的锁定和解锁操作以及重入锁定/解锁操作不需要任何内存同步效果。
发布于 2010-04-05 01:10:09
除了内存模型的语义保证的问题之外,我认为您正在发布的代码存在一些问题。
Lock实现时,不需要使用synchronized块。Lock的标准成语是在try-finally块中这样做,以防止意外解锁(因为在进入任何块时,锁不会自动释放,就像synchronized块一样)。您应该使用类似于以下内容的Lock:
lock.lock();
try {
//do stuff
}
finally {
lock.unlock();
}发布于 2010-04-05 01:11:53
现在,读取和写入易失性变量在操作排序之前和之后执行。写入易失性变量与释放监视器具有相同的效果,读取变量的效果与获取监视器的效果相同。下面的示例使它更加清晰:
volatile boolean memoryBarrier = false;
int unguardedValue = 0;
//thread a:
unguardedValue = 10;
memoryBarrier = true;
// thread b
if (memoryBarrier) {
// unguardedValue is guaranteed to be read as 10;
}但是,尽管如此,您提供的示例代码看起来并没有真正使用ReentrantLock,因为它是为使用而设计的。
Lock的使用,加上syncronized的内置关键字,可以有效地访问已经是单线程的锁,这样Lock就没有机会做任何真正的工作。Lock应该按照下面的模式进行,这在Lock的java文档中得到了概述lock.readLock().lock();
try {
// Do work
} finally {
lock.readLock.unlock();
}https://stackoverflow.com/questions/2576443
复制相似问题