Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我是否需要使用volatile if update to other thread';缓存不是时间限制_Java_Multithreading_Thread Safety_Volatile - Fatal编程技术网

Java 我是否需要使用volatile if update to other thread';缓存不是时间限制

Java 我是否需要使用volatile if update to other thread';缓存不是时间限制,java,multithreading,thread-safety,volatile,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次/秒 另一个线程监视某个文件以在期间内使用s

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

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的回答。

更好地使用,您不需要使用volatile变量。
get
调用应为ReadLocked(共享),而
set
调用应为WriteLocked(独占)。一旦所有线程都获得各自的读锁,这些更改就会在所有线程中更新

所有实现都必须保证内存 写回操作的同步效果(如 锁定接口)也保持关联的读锁。 也就是说,成功获取读取锁的线程将看到所有 上次发布写锁时所做的更新

示例代码:

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();
        }
    }
}

你为什么不跑几次自己看看呢为什么不同步get/setmethods@alfasin“运行几次”是计算并发边缘情况的糟糕建议。@Chryly是真的,但在这种情况下,他将获得一致的行为(提示:他所谓的“最坏情况”)@alfasin他可能在本地x86上获得一致的行为,但如果他尝试将其移植到ARM,任何事情都可能发生变化。这就是为什么这是一个糟糕的想法。读写锁是允许的解决方案。我只是想知道使用纯Java是否可以接受?是的,读取线程可能在值得到更新后读取旧值。但正如我所说,很少时间阅读旧价值观是可以接受的。我想知道旧值是否会永远留在CPU缓存中。不客气。这种锁的设计是为了频繁阅读而不是频繁写作。此外,每次“读取”,在修改后,都保证看到更新。如果操作只是交换单个变量,那么Volatile变量或原子对象也可以用于此目的。如果您想执行一系列步骤,那么锁定是最好的方法。如果您想使用普通java,没有易失性/原子对象,那么读取旧值的线程将永远看不到新值,除非线程执行具有“之前发生”关系的
操作。例如:同步或类似的东西。只有这样,所有的变量才会刷新。如果线程没有这样的操作,它将永远看不到更新。-进一步阅读。在我提到的锁的例子中,它们是
操作
满足关系发生之前的情况。因此,writer线程所做的更新在reader线程中可见。谢谢,before关系正是我问题的答案。