如果更新到其他线程'缓存不是时间约束,我需要使用volatile吗?

时间:2015-07-17 03:08:59

标签: java multithreading thread-safety volatile

我有一个带有一个方法的单例对象:

class static single
{
  String static somefileContent;
   public static void set(String str){somefileContent=str;}
   public static String get(){return somefileContent;}
}

我有两个帖子,

一个线程在操作中查询来自single.get()的内容,大约100次/秒。

另一个线程监视一些文件,用句点中的set()方法更新字符串,如果文件被修改,则刷新内容。

少数操作使用旧的字符串值是可以接受的。

我的问题是:我是否应该使用volatile,因为它不是时间限制的?

如果发生最坏情况,读取线程是否永远不会更新?

我只是想知道使用普通Java会发生什么?是的,读取线程可以在值更新后读取旧值。但就像我说的那样,读几次旧值是可以接受的。我想知道旧值是否永远存在于CPU缓存中。

感谢Vaspar的回答。

1 个答案:

答案 0 :(得分:1)

更好地使用ReentrantReadWriteLock并且您不需要使用volatile变量。 get调用应该是ReadLocked,它是共享的,而set调用应该是WriteLocked,它是独占的。所有线程一旦获得各自的ReadLocks,更新就会更新。

  

所有ReadWriteLock实现必须保证内存   writeLock操作的同步效果(如   锁定接口)也相对于相关的readLock保持。   也就是说,成功获取读锁定的线程将会看到所有   在先前发布的写锁定时进行的更新。

示例代码:

import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;


public class Single {
    private static String                       somefileContent = null;
    private static final ReentrantReadWriteLock readWriteLock   = new ReentrantReadWriteLock();
    private static final ReadLock               readLock        = readWriteLock.readLock();
    private static final WriteLock              writeLock       = readWriteLock.writeLock();

    public static String get() {
        try {
            readLock.lock();
            return somefileContent;
        } finally {
            readLock.unlock();
        }
    }

    public static void set(String str) {
        try {
            writeLock.lock();
            somefileContent = str;
        } finally {
            writeLock.unlock();
        }
    }
}