33import java .util .ArrayList ;
44import java .util .List ;
55import java .util .Map ;
6+ import java .util .concurrent .locks .ReentrantReadWriteLock ;
67import java .util .function .Consumer ;
78
89public class ConfigCatHooks {
9- private final Object sync = new Object ( );
10+ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock ( true );
1011 private final List <Consumer <Map <String , Setting >>> onConfigChanged = new ArrayList <>();
1112 private final List <Runnable > onClientReady = new ArrayList <>();
1213 private final List <Consumer <EvaluationDetails <Object >>> onFlagEvaluated = new ArrayList <>();
@@ -22,8 +23,11 @@ public class ConfigCatHooks {
2223 * @param callback the method to call when the event fires.
2324 */
2425 public void addOnClientReady (Runnable callback ) {
25- synchronized (sync ) {
26+ lock .writeLock ().lock ();
27+ try {
2628 this .onClientReady .add (callback );
29+ } finally {
30+ lock .writeLock ().unlock ();
2731 }
2832 }
2933
@@ -34,8 +38,11 @@ public void addOnClientReady(Runnable callback) {
3438 * @param callback the method to call when the event fires.
3539 */
3640 public void addOnConfigChanged (Consumer <Map <String , Setting >> callback ) {
37- synchronized (sync ) {
41+ lock .writeLock ().lock ();
42+ try {
3843 this .onConfigChanged .add (callback );
44+ } finally {
45+ lock .writeLock ().unlock ();
3946 }
4047 }
4148
@@ -45,8 +52,11 @@ public void addOnConfigChanged(Consumer<Map<String, Setting>> callback) {
4552 * @param callback the method to call when the event fires.
4653 */
4754 public void addOnError (Consumer <String > callback ) {
48- synchronized (sync ) {
55+ lock .writeLock ().lock ();
56+ try {
4957 this .onError .add (callback );
58+ } finally {
59+ lock .writeLock ().unlock ();
5060 }
5161 }
5262
@@ -57,49 +67,67 @@ public void addOnError(Consumer<String> callback) {
5767 * @param callback the method to call when the event fires.
5868 */
5969 public void addOnFlagEvaluated (Consumer <EvaluationDetails <Object >> callback ) {
60- synchronized (sync ) {
70+ lock .writeLock ().lock ();
71+ try {
6172 this .onFlagEvaluated .add (callback );
73+ } finally {
74+ lock .writeLock ().unlock ();
6275 }
6376 }
6477
6578 void invokeOnClientReady () {
66- synchronized (sync ) {
79+ lock .readLock ().lock ();
80+ try {
6781 for (Runnable func : this .onClientReady ) {
6882 func .run ();
6983 }
84+ } finally {
85+ lock .readLock ().unlock ();
7086 }
7187 }
7288
7389 void invokeOnError (String error ) {
74- synchronized (sync ) {
90+ lock .readLock ().lock ();
91+ try {
7592 for (Consumer <String > func : this .onError ) {
7693 func .accept (error );
7794 }
95+ } finally {
96+ lock .readLock ().unlock ();
7897 }
7998 }
8099
81100 void invokeOnConfigChanged (Map <String , Setting > settingMap ) {
82- synchronized (sync ) {
101+ lock .readLock ().lock ();
102+ try {
83103 for (Consumer <Map <String , Setting >> func : this .onConfigChanged ) {
84104 func .accept (settingMap );
85105 }
106+ } finally {
107+ lock .readLock ().unlock ();
86108 }
87109 }
88110
89111 void invokeOnFlagEvaluated (EvaluationDetails <Object > evaluationDetails ) {
90- synchronized (sync ) {
112+ lock .readLock ().lock ();
113+ try {
91114 for (Consumer <EvaluationDetails <Object >> func : this .onFlagEvaluated ) {
92115 func .accept (evaluationDetails );
93116 }
117+ } finally {
118+ lock .readLock ().unlock ();
94119 }
95120 }
96121
97122 void clear () {
98- synchronized (sync ) {
123+ lock .writeLock ().lock ();
124+ try {
99125 this .onConfigChanged .clear ();
100126 this .onError .clear ();
101127 this .onFlagEvaluated .clear ();
102128 this .onClientReady .clear ();
129+ } finally {
130+ lock .writeLock ().unlock ();
103131 }
104132 }
105133}
0 commit comments