1118 |
|
int b = batch; |
1119 |
|
int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1; |
1120 |
|
if (!exhausted && |
1121 |
< |
((h = current) != null || (h = q.first) != null) && |
1122 |
< |
h.next != null) { |
1121 |
> |
(((h = current) != null && h != h.next) |
1122 |
> |
|| (h = q.first) != null) |
1123 |
> |
&& h.next != null) { |
1124 |
|
Object[] a = new Object[n]; |
1125 |
|
final ReentrantLock lock = q.lock; |
1126 |
|
int i = 0; |
1127 |
|
Node<E> p = current; |
1128 |
|
lock.lock(); |
1129 |
|
try { |
1130 |
< |
if (p != null || (p = q.first) != null) { |
1130 |
> |
if ((p != null && p != p.next) || (p = q.first) != null) { |
1131 |
|
do { |
1132 |
|
if ((a[i] = p.item) != null) |
1133 |
|
++i; |
1155 |
|
|
1156 |
|
public void forEachRemaining(Consumer<? super E> action) { |
1157 |
|
if (action == null) throw new NullPointerException(); |
1157 |
– |
final LinkedBlockingDeque<E> q = this.queue; |
1158 |
– |
final ReentrantLock lock = q.lock; |
1158 |
|
if (!exhausted) { |
1159 |
|
exhausted = true; |
1160 |
|
Node<E> p = current; |
1161 |
+ |
current = null; |
1162 |
+ |
final LinkedBlockingDeque<E> q = this.queue; |
1163 |
+ |
final ReentrantLock lock = q.lock; |
1164 |
|
do { |
1165 |
< |
E e = null; |
1165 |
> |
E e; |
1166 |
|
lock.lock(); |
1167 |
|
try { |
1168 |
|
if (p == null) |
1169 |
|
p = q.first; |
1170 |
< |
while (p != null) { |
1170 |
> |
do { |
1171 |
> |
if (p == null) |
1172 |
> |
return; |
1173 |
|
e = p.item; |
1174 |
< |
p = p.next; |
1175 |
< |
if (e != null) |
1172 |
< |
break; |
1173 |
< |
} |
1174 |
> |
if (p == (p = p.next)) p = q.first; |
1175 |
> |
} while (e == null); |
1176 |
|
} finally { |
1177 |
|
lock.unlock(); |
1178 |
|
} |
1179 |
< |
if (e != null) |
1178 |
< |
action.accept(e); |
1179 |
> |
action.accept(e); |
1180 |
|
} while (p != null); |
1181 |
|
} |
1182 |
|
} |
1183 |
|
|
1184 |
|
public boolean tryAdvance(Consumer<? super E> action) { |
1185 |
|
if (action == null) throw new NullPointerException(); |
1186 |
< |
final LinkedBlockingDeque<E> q = this.queue; |
1187 |
< |
final ReentrantLock lock = q.lock; |
1188 |
< |
if (!exhausted) { |
1189 |
< |
E e = null; |
1186 |
> |
if (!exhausted) findElement: { |
1187 |
> |
final LinkedBlockingDeque<E> q = this.queue; |
1188 |
> |
final ReentrantLock lock = q.lock; |
1189 |
> |
E e; |
1190 |
> |
Node<E> p = current; |
1191 |
|
lock.lock(); |
1192 |
|
try { |
1193 |
< |
if (current == null) |
1194 |
< |
current = q.first; |
1195 |
< |
while (current != null) { |
1196 |
< |
e = current.item; |
1197 |
< |
current = current.next; |
1198 |
< |
if (e != null) |
1199 |
< |
break; |
1198 |
< |
} |
1193 |
> |
if (p == null) |
1194 |
> |
p = q.first; |
1195 |
> |
do { |
1196 |
> |
if (p == null) break findElement; |
1197 |
> |
e = p.item; |
1198 |
> |
if (p == (p = p.next)) p = q.first; |
1199 |
> |
} while (e == null); |
1200 |
|
} finally { |
1201 |
|
lock.unlock(); |
1202 |
|
} |
1203 |
< |
if (current == null) |
1203 |
> |
action.accept(e); |
1204 |
> |
if ((current = p) == null) |
1205 |
|
exhausted = true; |
1206 |
< |
if (e != null) { |
1205 |
< |
action.accept(e); |
1206 |
< |
return true; |
1207 |
< |
} |
1206 |
> |
return true; |
1207 |
|
} |
1208 |
+ |
current = null; |
1209 |
+ |
exhausted = true; |
1210 |
|
return false; |
1211 |
|
} |
1212 |
|
|
1213 |
|
public int characteristics() { |
1214 |
< |
return Spliterator.ORDERED | Spliterator.NONNULL | |
1215 |
< |
Spliterator.CONCURRENT; |
1214 |
> |
return (Spliterator.ORDERED | |
1215 |
> |
Spliterator.NONNULL | |
1216 |
> |
Spliterator.CONCURRENT); |
1217 |
|
} |
1218 |
|
} |
1219 |
|
|