刷新cahche任务线程安全

时间:2018-02-28 05:07:41

标签: java thread-safety

public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
  final String packageName = this.cordova.getActivity().getPackageName();
  final PackageManager pm = this.cordova.getActivity().getPackageManager();

  ApplicationInfo appInfo;
  try {
    appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
    if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
      // debug = true
      handler.proceed();
      return;
    } else {
      // debug = false
      // THIS IS WHAT YOU NEED TO CHANGE:
      // 1. COMMENT THIS LINE
      // super.onReceivedSslError(view, handler, error);
      // 2. ADD THESE TWO LINES
      // ---->
      handler.proceed();
      return;
      // <----
    }
  } catch (NameNotFoundException e) {
    // When it doubt, lock it out!
    super.onReceivedSslError(view, handler, error);
  }
}

我有一个如上所示的缓存刷新逻辑,并希望确保它是线程安全且正确的方法。

我有一个后台线程定期调用public class Test { Set<Integer> cache = Sets.newConcurrentHashSet(); // multiple threads call this public boolean contain(int num) { return cache.contains(num); } // background thread periodically calls this private void refresh() { Set<Integer> newSet = getNums(); cache = newSet; // is this assignment thread safe? } private Set<Integer> getNums() { Set<Integer> newSet = Sets.newConcurrentHashSet(); // read numbers from file and add them to newSet return newSet; } } refresh由多个线程调用。

contain中,我有refresh。这是线程安全的吗?如果cache = newSetcache.contains在同一时间执行会发生什么?当后台线程正在运行cache = newSet时,一个线程可能正在调用contains

此外,由于refresh仅调用contain功能,我是否需要cache.contains

1 个答案:

答案 0 :(得分:1)

  

在刷新时,我有cache = newSet。这是线程安全的吗?

由于缓存未标有volatile关键字,因此不是100%线程安全的。在这种情况下,即使赋值是JVM中的原子操作,当一个线程访问cache.contains而另一个线程执行赋值(刷新)时,两个线程可能都不会立即看到更改。

由于volatile关键字可以保证在发生更改时多个线程之间共享状态的可见性。

  

另外,由于只包含call cache.contains函数,我是否需要   newConcurrentHashSet?

如果任何线程都没有对cache进行修改,但只读它就应该使用非并发集。但在这种情况下,您需要cache变量private

    public class Test {

        private volatile Set<Integer> cache = Sets.newConcurrentHashSet();

        // multiple threads call this
        public boolean contain(int num) {
            return cache.contains(num);
        }

        // background thread periodically calls this
        private void refresh() {
            Set<Integer> newSet = getNums();
            cache = newSet; // is this assignment thread safe?
        }

        private Set<Integer> getNums() {
             Set<Integer> newSet = Sets.newConcurrentHashSet();
             // read numbers from file and add them to newSet
             return newSet;
        }
    }