0

I need to cache the least recent result (say 10,000) of a concurrent system, and random access them. Since most of concurrent cache are based on linked list, I'm wondering if there is a thread safe random access circular array in java?

los
  • 61
  • 5
  • Can you give more details on how you need to use it? In example, could Guava's in-memory cache work for you? – Daniele Mar 08 '20 at 17:08
  • Assuming by "random access" you mean access by index? If so, is it by LRU order? If so, why do you need that? What are you actually trying to achieve? – Bohemian Mar 08 '20 at 18:08
  • @Daniele Local cache for fail over, write operation is much more than read – los Mar 09 '20 at 06:07
  • @Bohemian Yes, by index, but restriction is weaker than LRU, cause it's only used for failover – los Mar 09 '20 at 06:11
  • 1
    The locking issues of a linked list shouldn't be a problem in a well designed cache. If you need LRU then [ConcurrentLinkedHashMap](https://github.com/ben-manes/concurrentlinkedhashmap) or [Guava's Cache](https://github.com/google/guava/wiki/CachesExplained) should suffice. If you can leverage a smarter eviction policy, then [Caffeine](https://github.com/ben-manes/caffeine) is preferrable. See [benchmarks](https://github.com/ben-manes/caffeine/wiki/Benchmarks#server-class). – Ben Manes Mar 09 '20 at 06:20
  • @BenManes No, I cannot use linked list, random access is a must – los Mar 09 '20 at 07:46
  • What does that mean? The random access of the map entries is supported. – Ben Manes Mar 09 '20 at 07:49
  • @BenManes The problem is, i don't have a key to describe requests: every request is different with each others, they are basically user actions. So i decide to cache a list of response and combine them as a failover response. – los Mar 09 '20 at 07:57
  • Then I suppose a lock-free circular ring buffer and fifo or clock eviction is a reasonable strategy. – Ben Manes Mar 09 '20 at 08:00
  • You can use AtomicReferenceArray to build your cache on top of. – Ben Manes Mar 09 '20 at 08:04
  • can you explain how you "random access" your items? I assume you would use some sort of key? – Daniele Mar 09 '20 at 12:22
  • @los how are random access and "failover" related? – Bohemian Mar 09 '20 at 22:35
  • @los how are "random access" and "failover" related? Again I ask, what are you actually trying to do? – Bohemian Mar 09 '20 at 22:41

2 Answers2

0

For caches without timeout, I often use the ConcurrentHashMap. You may also take a look at the CopyOnWriteArrayList.

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

Stefan
  • 1,789
  • 1
  • 11
  • 16
  • According to the document, copyOnWriteArrayList is more efficient when traversal operations vastly outnumber mutations. But we have much more write than read – los Mar 09 '20 at 07:50
  • Then you may use a traditional array and synchronize access to it: ```List list = Collections.synchronizedList(new ArrayList()); ``` – Stefan Mar 09 '20 at 16:28
0

There is an implementation of CircularFifoQueue in the Apache Commons Collections library. It contains a get() method for random access. For a thread-safe version, you can wrap its instance with the SynchronizedQueue wrapper. Another solution is the cyclic ArrayList/Vector implementation, described in detail here.

Marek Gregor
  • 3,691
  • 2
  • 26
  • 28