我是否需要在读写器场景中使这两个变量都不稳定



我们有两个线程。一个是读者。另一个是共享以下两个变量的编写器线程:

Object data
boolean ready

我需要使两者都不稳定吗?这足以让"现成"变得不稳定吗?

write() {
    data = <some data>
    ready = true;
}
read() {
    if (ready) {
        consume(data);
        ready = false;
    } 
}

我需要使这两个变量都不稳定吗?

基于我对java内存模型的有限理解,我认为我只需要让"ready"变得易失性,因为读/写"ready"之前的所有代码都发生在读/写"ready"变量之后的代码之前?

更新:为了这个问题的目的,假设原子性不是一个问题。数据的产生和消耗是原子性的。

挥发物在使用时有利于发出信号,但不利于原子性。您需要原子性,以防数据在消耗时得到更新,但尚未设置就绪。

正如其他人在原子性方面明确指出的那样,您可以通过使用ReadWriteLock来增加并发性。更多详细信息,请访问:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReadWriteLock.html

在这种情况下,可能有多个读取器线程,并且写锁是独占的。

您的问题与SO上的另一个问题类似。

正如我在那里所说,如果数据就绪仅由一个线程更新,那么volatile对两者都很好。Atomic适用于多个作者。

您的理解是正确的。

当线程1写入一个易失性变量,随后线程2读取该易失性可变变量时,在易失性写入之前线程1可见的所有变量在读易失性之后对线程2可见。就像线程1离开一个同步块,然后线程2进入一样。

但这不是一种推荐的提供可见性的方式,因为它不像进入/退出同步块或获取/释放锁那样明确地显示自己。

在您的示例中,易失性变量对于状态标志(如ready)很方便,但只能保证以线程安全的方式访问值,不能保证其余块按顺序执行。

在您的示例中,write(data)read()onsump(data第二次调用写入(数据)

例如:

线程1启动:写入(data1)

线程1结束://就绪:true,data=data1

线程2启动:read()//consume(data1)需要一段时间。

线程3启动:写入(data2)//ready=true,data=data2

线程2结束:read()//consume(data2)finished,ready=false,data=data2

相关内容

  • 没有找到相关文章

最新更新