20
20
import java .util .Collection ;
21
21
import java .util .LinkedList ;
22
22
import java .util .List ;
23
+ import java .util .concurrent .locks .ReentrantLock ;
23
24
24
25
import rx .Subscription ;
25
- import rx .exceptions .* ;
26
+ import rx .exceptions .Exceptions ;
26
27
27
28
/**
28
29
* Subscription that represents a group of Subscriptions that are unsubscribed together.
@@ -33,6 +34,7 @@ public final class SubscriptionList implements Subscription {
33
34
34
35
private LinkedList <Subscription > subscriptions ;
35
36
private volatile boolean unsubscribed ;
37
+ private final ReentrantLock lock = new ReentrantLock ();
36
38
37
39
public SubscriptionList () {
38
40
}
@@ -64,14 +66,19 @@ public void add(final Subscription s) {
64
66
return ;
65
67
}
66
68
if (!unsubscribed ) {
67
- synchronized (this ) {
69
+ lock .lock ();
70
+ try {
68
71
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 ;
71
76
}
72
- subscriptions .add (s );
77
+ subs .add (s );
73
78
return ;
74
79
}
80
+ } finally {
81
+ lock .unlock ();
75
82
}
76
83
}
77
84
// 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) {
81
88
public void remove (final Subscription s ) {
82
89
if (!unsubscribed ) {
83
90
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 ) {
86
95
return ;
87
96
}
88
- unsubscribe = subscriptions .remove (s );
97
+ unsubscribe = subs .remove (s );
98
+ } finally {
99
+ lock .unlock ();
89
100
}
90
101
if (unsubscribe ) {
91
102
// 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) {
102
113
public void unsubscribe () {
103
114
if (!unsubscribed ) {
104
115
List <Subscription > list ;
105
- synchronized (this ) {
116
+ lock .lock ();
117
+ try {
106
118
if (unsubscribed ) {
107
119
return ;
108
120
}
109
121
unsubscribed = true ;
110
122
list = subscriptions ;
111
123
subscriptions = null ;
124
+ } finally {
125
+ lock .unlock ();
112
126
}
113
127
// we will only get here once
114
128
unsubscribeFromAll (list );
@@ -136,9 +150,12 @@ private static void unsubscribeFromAll(Collection<Subscription> subscriptions) {
136
150
public void clear () {
137
151
if (!unsubscribed ) {
138
152
List <Subscription > list ;
139
- synchronized (this ) {
153
+ lock .lock ();
154
+ try {
140
155
list = subscriptions ;
141
156
subscriptions = null ;
157
+ } finally {
158
+ lock .unlock ();
142
159
}
143
160
unsubscribeFromAll (list );
144
161
}
@@ -149,8 +166,11 @@ public void clear() {
149
166
*/
150
167
public boolean hasSubscriptions () {
151
168
if (!unsubscribed ) {
152
- synchronized (this ) {
169
+ lock .lock ();
170
+ try {
153
171
return !unsubscribed && subscriptions != null && !subscriptions .isEmpty ();
172
+ } finally {
173
+ lock .unlock ();
154
174
}
155
175
}
156
176
return false ;
0 commit comments