1
14
15 package com.liferay.portal.kernel.concurrent;
16
17 import com.liferay.portal.kernel.util.StringBundler;
18 import com.liferay.portal.kernel.util.Validator;
19
20 import java.util.concurrent.atomic.AtomicMarkableReference;
21
22
27 public abstract class IncreasableEntry<K, V> {
28
29 public IncreasableEntry(K key, V value) {
30 _key = key;
31 _markedValue = new AtomicMarkableReference<V>(value, false);
32 }
33
34 public abstract V doIncrease(V originalValue, V deltaValue);
35
36 public boolean equals(Object obj) {
37 if (this == obj) {
38 return true;
39 }
40
41 if (!(obj instanceof IncreasableEntry<?, ?>)) {
42 return false;
43 }
44
45 IncreasableEntry<K, V> increasableEntry = (IncreasableEntry<K, V>)obj;
46
47 if (Validator.equals(_key, increasableEntry._key) &&
48 Validator.equals(
49 _markedValue.getReference(),
50 increasableEntry._markedValue.getReference())) {
51
52 return true;
53 }
54
55 return false;
56 }
57
58 public final K getKey() {
59 return _key;
60 }
61
62 public final V getValue() {
63 while (true) {
64 V value = _markedValue.getReference();
65
66 if (_markedValue.attemptMark(value, true)) {
67 return value;
68 }
69 }
70 }
71
72 public int hashCode() {
73 int hash = 77;
74
75 if (_key != null) {
76 hash += _key.hashCode();
77 }
78
79 hash = 11 * hash;
80
81 V value = _markedValue.getReference();
82
83 if (value != null) {
84 hash += value.hashCode();
85 }
86
87 return hash;
88 }
89
90 public final boolean increase(V deltaValue) {
91 boolean[] marked = {false};
92
93 while (true) {
94 V originalValue = _markedValue.get(marked);
95
96 if (marked[0]) {
97 return false;
98 }
99 else {
100 V newValue = doIncrease(originalValue, deltaValue);
101
102 if (_markedValue.compareAndSet(
103 originalValue, newValue, false, false)) {
104
105 return true;
106 }
107 }
108 }
109 }
110
111 public String toString() {
112 StringBundler sb = new StringBundler(5);
113
114 sb.append("{key=");
115 sb.append(String.valueOf(_key.toString()));
116 sb.append(", value=");
117 sb.append(String.valueOf(_markedValue.getReference()));
118 sb.append("}");
119
120 return sb.toString();
121 }
122
123 private final K _key;
124 private final AtomicMarkableReference<V> _markedValue;
125
126 }