11package com .fasterxml .jackson .core .util ;
22
33import java .util .concurrent .ConcurrentHashMap ;
4+ import java .util .concurrent .locks .ReentrantLock ;
45
56/**
67 * Singleton class that adds a simple first-level cache in front of
@@ -29,7 +30,7 @@ public final class InternCache
2930 * cases where multiple threads might try to concurrently
3031 * flush the map.
3132 */
32- private final Object lock = new Object ();
33+ private final ReentrantLock lock = new ReentrantLock ();
3334
3435 public InternCache () { this (MAX_ENTRIES , 0.8f , 4 ); }
3536
@@ -47,13 +48,19 @@ public String intern(String input) {
4748 * we are simply likely to keep on clearing same, commonly used entries.
4849 */
4950 if (size () >= MAX_ENTRIES ) {
50- /* Not incorrect wrt well-known double-locking anti-pattern because underlying
51- * storage gives close enough answer to real one here; and we are
52- * more concerned with flooding than starvation.
51+ /* As of 2.18, the limit is not strictly enforced, but we do try to
52+ * clear entries if we have reached the limit. We do not expect to
53+ * go too much over the limit, and if we do, it's not a huge problem.
54+ * If some other thread has the lock, we will not clear but the lock should
55+ * not be held for long, so another thread should be able to clear in the near future.
5356 */
54- synchronized (lock ) {
55- if (size () >= MAX_ENTRIES ) {
56- clear ();
57+ if (lock .tryLock ()) {
58+ try {
59+ if (size () >= MAX_ENTRIES ) {
60+ clear ();
61+ }
62+ } finally {
63+ lock .unlock ();
5764 }
5865 }
5966 }
0 commit comments