0

My use case is this:

I need to cache a set of strings for frequent read access. The cache is updated by a daemon thread periodically. Moreover, the cache element will never get updated individually, it would always be

set.clear();set.addAll(List)
I'm currently using a HashSet protected by an ReentrantReadWriteLock. Is there a better way to do this?
bohanl
  • 1,885
  • 4
  • 17
  • 33
  • You could use one of the many robust Java caches that already exist. See also [this question](http://stackoverflow.com/questions/575685/looking-for-simple-java-in-memory-cache). – Elliott Frisch Jun 12 '15 at 05:39
  • Could you name a few? I thought about Guava's LoadingCache but it takes more memory than I need, I don't really need a map in this case. – bohanl Jun 12 '15 at 05:40
  • 1
    In what way does it take more memory than you need? That's a very vague assertion. The JVM manages your memory, and I would prefer an existing solution to rolling my own. And yes, [`LoadingCache`](https://code.google.com/p/guava-libraries/wiki/CachesExplained) looks fine. – Elliott Frisch Jun 12 '15 at 05:42
  • LoadingCache, which is essentially a hash map, whereas I only need to cache a set of strings. How does JVM optimize in this case? My set could have tons of entries. – bohanl Jun 12 '15 at 05:46
  • Read the Javadoc. And Java (especially 64-bit Java) can address *tons* of memory. – Elliott Frisch Jun 12 '15 at 05:49
  • 2
    @bohanl HashSet in the jdk is implemented with a HashMap internally... – assylias Jun 12 '15 at 05:50
  • 1
    A `Set` doesn't take any less memory than a `Map` for any of the JDK's implementations. – Louis Wasserman Jun 13 '15 at 06:49

1 Answers1

2

One option would be a volatile set:

private volatile Set<String> set = new HashSet<> ();

public void update() {
  Set<String> newSet = getNewData();
  set = newSet;
}

This is thread safe (if you don't let other code access the set itself) and does not require locking. One drawback is that you hold both sets in memory until the next GC (not sure how much space is used per entry - to be tested).

assylias
  • 321,522
  • 82
  • 660
  • 783