1
1
package com .fasterxml .jackson .core .util ;
2
2
3
3
import java .util .concurrent .ConcurrentHashMap ;
4
+ import java .util .concurrent .locks .ReentrantLock ;
4
5
5
6
/**
6
7
* Singleton class that adds a simple first-level cache in front of
@@ -29,7 +30,7 @@ public final class InternCache
29
30
* cases where multiple threads might try to concurrently
30
31
* flush the map.
31
32
*/
32
- private final Object lock = new Object ();
33
+ private final ReentrantLock lock = new ReentrantLock ();
33
34
34
35
public InternCache () { this (MAX_ENTRIES , 0.8f , 4 ); }
35
36
@@ -47,13 +48,19 @@ public String intern(String input) {
47
48
* we are simply likely to keep on clearing same, commonly used entries.
48
49
*/
49
50
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.
53
56
*/
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 ();
57
64
}
58
65
}
59
66
}
0 commit comments