3
public class IntermediateMessage {

    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final Lock read = readWriteLock.readLock();
    private final Lock write = readWriteLock.writeLock();

    private volatile double ratio;

    public IntermediateMessage(){
        this.ratio=1.0d;
    }

    public IntermediateMessage(double ratio){
        this.ratio = ratio;
    }

    public double getRatio(){
        read.lock();
        try{
            return this.ratio;
        }
        finally{
            read.unlock();
        }
    }

    public void setRatio(double ratio){ 
        write.lock();
        try{
            this.ratio = ratio;
        }
        finally{
            write.unlock();
        }
    }
}

我有这个对象。我的应用程序中有这个对象的一个​​实例,一个线程正在写入比率变量,而其他线程正在读取比率。这是保护比率变量的正确方法吗?我需要将比率声明为 volatile 吗?

4

5 回答 5

1

您在同步上做了一些矫枉过正的工作,这会导致效率低下。

java关键字“ volatile ”表示该变量不会被缓存,并且它将具有多个线程的同步访问。

因此,您正在锁定一个默认情况下已经同步的变量。

因此,您应该删除 volatile 关键字,或者删除可重入锁。可能是易失性的,因为您将以当前同步的方式进行多次读取,从而提高效率。

于 2013-05-29T01:23:21.387 回答
1

对于读取/写入原始值,volatile单独使用就足够了。

于 2013-05-29T01:35:15.600 回答
1

你需要锁定吗?根据您描述的有限要求,很可能不会。但是请阅读此内容以确保...

  • 你只有一个线程写作。
    • 这意味着变量值永远不会“过时”,因为竞争的作者互相“破坏”(没有可能的竞争条件)。 因此,在孤立地考虑单个变量时,不需要锁定来提供完整性。
  • 您没有提到是否需要对多个变量进行某种形式的原子、一致的修改。我认为不是。
    • IFratio必须始终与其他变量一致(例如在其他对象中)——即,如果一组变量必须作为一个组同步变化,而没有人只读取部分变化——那么需要锁定以使该组具有原子一致性变量。然后一致的变量必须在单个锁定区域内一起修改,并且读取器必须在读取任何这些变量集之前获得相同的锁(如果需要,在阻塞状态下等待)。
    • IF 比率可以作为一个单独的变量随时更改,不需要与其他变量保持一致,则不需要锁定,为一组变量提供原子一致性

你需要 volatile 修饰符吗?嗯,是!

  • 您有多个线程正在阅读。
  • 变量可以随时更改,包括即将被读取之前的瞬间。
  • volatile修饰符用于多线程应用程序中,以保证“readers”读取的值始终与“writers”写入的值匹配。
于 2013-05-29T04:59:01.043 回答
0

假设两个线程试图在同一个对象上读取和写入,并且您希望保持数据完整性。只需让您的 getter 和 setter 同步即可。当一个方法被同步时,只有一个线程能够调用一个同步方法。当一个线程正在执行同步方法之一时,没有其他线程能够调用任何同步方法。因此,在您的情况下,如果您的 get & set 方法同步,您可以确定一个线程是否正在读/写,没有其他线程可以进行读/写。

希望能帮助到你!

于 2013-05-29T01:33:33.887 回答
-1

ratiofinal,它将是线程安全的。

于 2013-05-29T03:20:25.950 回答