Skip to content

Commit 642eb99

Browse files
akarnokdakarnokd
akarnokd
authored and
akarnokd
committed
SubscriptionList to use j.u.c.Lock
1 parent bada414 commit 642eb99

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

src/main/java/rx/internal/util/SubscriptionList.java

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
import java.util.Collection;
2121
import java.util.LinkedList;
2222
import java.util.List;
23+
import java.util.concurrent.locks.ReentrantLock;
2324

2425
import rx.Subscription;
25-
import rx.exceptions.*;
26+
import rx.exceptions.Exceptions;
2627

2728
/**
2829
* Subscription that represents a group of Subscriptions that are unsubscribed together.
@@ -33,6 +34,7 @@ public final class SubscriptionList implements Subscription {
3334

3435
private LinkedList<Subscription> subscriptions;
3536
private volatile boolean unsubscribed;
37+
private final ReentrantLock lock = new ReentrantLock();
3638

3739
public SubscriptionList() {
3840
}
@@ -64,14 +66,19 @@ public void add(final Subscription s) {
6466
return;
6567
}
6668
if (!unsubscribed) {
67-
synchronized (this) {
69+
lock.lock();
70+
try {
6871
if (!unsubscribed) {
69-
if (subscriptions == null) {
70-
subscriptions = new LinkedList<Subscription>();
72+
LinkedList<Subscription> subs = subscriptions;
73+
if (subs == null) {
74+
subs = new LinkedList<Subscription>();
75+
subscriptions = subs;
7176
}
72-
subscriptions.add(s);
77+
subs.add(s);
7378
return;
7479
}
80+
} finally {
81+
lock.unlock();
7582
}
7683
}
7784
// call after leaving the synchronized block so we're not holding a lock while executing this
@@ -81,11 +88,15 @@ public void add(final Subscription s) {
8188
public void remove(final Subscription s) {
8289
if (!unsubscribed) {
8390
boolean unsubscribe = false;
84-
synchronized (this) {
85-
if (unsubscribed || subscriptions == null) {
91+
lock.lock();
92+
try {
93+
LinkedList<Subscription> subs = subscriptions;
94+
if (unsubscribed || subs == null) {
8695
return;
8796
}
88-
unsubscribe = subscriptions.remove(s);
97+
unsubscribe = subs.remove(s);
98+
} finally {
99+
lock.unlock();
89100
}
90101
if (unsubscribe) {
91102
// if we removed successfully we then need to call unsubscribe on it (outside of the lock)
@@ -102,13 +113,16 @@ public void remove(final Subscription s) {
102113
public void unsubscribe() {
103114
if (!unsubscribed) {
104115
List<Subscription> list;
105-
synchronized (this) {
116+
lock.lock();
117+
try {
106118
if (unsubscribed) {
107119
return;
108120
}
109121
unsubscribed = true;
110122
list = subscriptions;
111123
subscriptions = null;
124+
} finally {
125+
lock.unlock();
112126
}
113127
// we will only get here once
114128
unsubscribeFromAll(list);
@@ -136,9 +150,12 @@ private static void unsubscribeFromAll(Collection<Subscription> subscriptions) {
136150
public void clear() {
137151
if (!unsubscribed) {
138152
List<Subscription> list;
139-
synchronized (this) {
153+
lock.lock();
154+
try {
140155
list = subscriptions;
141156
subscriptions = null;
157+
} finally {
158+
lock.unlock();
142159
}
143160
unsubscribeFromAll(list);
144161
}
@@ -149,8 +166,11 @@ public void clear() {
149166
*/
150167
public boolean hasSubscriptions() {
151168
if (!unsubscribed) {
152-
synchronized (this) {
169+
lock.lock();
170+
try {
153171
return !unsubscribed && subscriptions != null && !subscriptions.isEmpty();
172+
} finally {
173+
lock.unlock();
154174
}
155175
}
156176
return false;

0 commit comments

Comments
 (0)