243 |
|
|
244 |
|
private static final Node<Object> PREV_TERMINATOR, NEXT_TERMINATOR; |
245 |
|
|
246 |
– |
static { |
247 |
– |
PREV_TERMINATOR = new Node<Object>(null); |
248 |
– |
PREV_TERMINATOR.next = PREV_TERMINATOR; |
249 |
– |
NEXT_TERMINATOR = new Node<Object>(null); |
250 |
– |
NEXT_TERMINATOR.prev = NEXT_TERMINATOR; |
251 |
– |
} |
252 |
– |
|
246 |
|
@SuppressWarnings("unchecked") |
247 |
|
Node<E> prevTerminator() { |
248 |
|
return (Node<E>) PREV_TERMINATOR; |
258 |
|
volatile E item; |
259 |
|
volatile Node<E> next; |
260 |
|
|
261 |
+ |
Node() { // default constructor for NEXT_TERMINATOR, PREV_TERMINATOR |
262 |
+ |
} |
263 |
+ |
|
264 |
|
/** |
265 |
|
* Constructs a new node. Uses relaxed write because item can |
266 |
|
* only be seen after publication via casNext or casPrev. |
290 |
|
} |
291 |
|
|
292 |
|
// Unsafe mechanics |
293 |
< |
|
294 |
< |
private static final sun.misc.Unsafe UNSAFE = |
295 |
< |
sun.misc.Unsafe.getUnsafe(); |
296 |
< |
private static final long prevOffset = |
297 |
< |
objectFieldOffset(UNSAFE, "prev", Node.class); |
298 |
< |
private static final long itemOffset = |
299 |
< |
objectFieldOffset(UNSAFE, "item", Node.class); |
300 |
< |
private static final long nextOffset = |
301 |
< |
objectFieldOffset(UNSAFE, "next", Node.class); |
293 |
> |
|
294 |
> |
private static final sun.misc.Unsafe UNSAFE; |
295 |
> |
private static final long prevOffset; |
296 |
> |
private static final long itemOffset; |
297 |
> |
private static final long nextOffset; |
298 |
> |
|
299 |
> |
static { |
300 |
> |
try { |
301 |
> |
UNSAFE = sun.misc.Unsafe.getUnsafe(); |
302 |
> |
Class k = Node.class; |
303 |
> |
prevOffset = UNSAFE.objectFieldOffset |
304 |
> |
(k.getDeclaredField("prev")); |
305 |
> |
itemOffset = UNSAFE.objectFieldOffset |
306 |
> |
(k.getDeclaredField("item")); |
307 |
> |
nextOffset = UNSAFE.objectFieldOffset |
308 |
> |
(k.getDeclaredField("next")); |
309 |
> |
} catch (Exception e) { |
310 |
> |
throw new Error(e); |
311 |
> |
} |
312 |
> |
} |
313 |
|
} |
314 |
|
|
315 |
|
/** |
1400 |
|
initHeadTail(h, t); |
1401 |
|
} |
1402 |
|
|
1396 |
– |
// Unsafe mechanics |
1397 |
– |
|
1398 |
– |
private static final sun.misc.Unsafe UNSAFE = |
1399 |
– |
sun.misc.Unsafe.getUnsafe(); |
1400 |
– |
private static final long headOffset = |
1401 |
– |
objectFieldOffset(UNSAFE, "head", ConcurrentLinkedDeque.class); |
1402 |
– |
private static final long tailOffset = |
1403 |
– |
objectFieldOffset(UNSAFE, "tail", ConcurrentLinkedDeque.class); |
1403 |
|
|
1404 |
|
private boolean casHead(Node<E> cmp, Node<E> val) { |
1405 |
|
return UNSAFE.compareAndSwapObject(this, headOffset, cmp, val); |
1409 |
|
return UNSAFE.compareAndSwapObject(this, tailOffset, cmp, val); |
1410 |
|
} |
1411 |
|
|
1412 |
< |
static long objectFieldOffset(sun.misc.Unsafe UNSAFE, |
1413 |
< |
String field, Class<?> klazz) { |
1412 |
> |
// Unsafe mechanics |
1413 |
> |
|
1414 |
> |
private static final sun.misc.Unsafe UNSAFE; |
1415 |
> |
private static final long headOffset; |
1416 |
> |
private static final long tailOffset; |
1417 |
> |
static { |
1418 |
> |
PREV_TERMINATOR = new Node<Object>(); |
1419 |
> |
PREV_TERMINATOR.next = PREV_TERMINATOR; |
1420 |
> |
NEXT_TERMINATOR = new Node<Object>(); |
1421 |
> |
NEXT_TERMINATOR.prev = NEXT_TERMINATOR; |
1422 |
|
try { |
1423 |
< |
return UNSAFE.objectFieldOffset(klazz.getDeclaredField(field)); |
1424 |
< |
} catch (NoSuchFieldException e) { |
1425 |
< |
// Convert Exception to corresponding Error |
1426 |
< |
NoSuchFieldError error = new NoSuchFieldError(field); |
1427 |
< |
error.initCause(e); |
1428 |
< |
throw error; |
1423 |
> |
UNSAFE = sun.misc.Unsafe.getUnsafe(); |
1424 |
> |
Class k = ConcurrentLinkedDeque.class; |
1425 |
> |
headOffset = UNSAFE.objectFieldOffset |
1426 |
> |
(k.getDeclaredField("head")); |
1427 |
> |
tailOffset = UNSAFE.objectFieldOffset |
1428 |
> |
(k.getDeclaredField("tail")); |
1429 |
> |
} catch (Exception e) { |
1430 |
> |
throw new Error(e); |
1431 |
|
} |
1432 |
|
} |
1433 |
|
} |