9 |
|
import java.util.*; |
10 |
|
|
11 |
|
/** |
12 |
< |
* A {@link Queue} in which each put must wait for a take, and vice |
13 |
< |
* versa. SynchronousQueues are similar to rendezvous channels used |
12 |
> |
* A {@linkplain BlockingQueue blocking queue} in which each <tt>put</tt> |
13 |
> |
* must wait for a <tt>take</tt>, and vice versa. |
14 |
> |
* A synchronous queue does not have any internal capacity - in particular |
15 |
> |
* it does not have a capacity of one. You cannot <tt>peek</tt> at a |
16 |
> |
* synchronous queue because an element is only present when you try to take |
17 |
> |
* it; you cannot add an element (using any method) unless another thread is |
18 |
> |
* trying to remove it; you cannot iterate as there is nothing to iterate. |
19 |
> |
* The <em>head</em> of the queue is the element that the first queued thread |
20 |
> |
* is trying to add to the queue; if there are no queued threads then no |
21 |
> |
* element is being added and the head is <tt>null</tt>. |
22 |
> |
* Many of the <tt>Collection</tt> methods make little or no sense for a |
23 |
> |
* synchronous queue. |
24 |
> |
* This queue does not permit <tt>null</tt> elements. |
25 |
> |
* <p>Synchronous queues are similar to rendezvous channels used |
26 |
|
* in CSP and Ada. They are well suited for handoff designs, in which |
27 |
|
* an object running in one thread must synch up with an object |
28 |
|
* running in another thread in order to hand it some information, |
302 |
|
} |
303 |
|
} |
304 |
|
|
305 |
+ |
/** |
306 |
+ |
* Creates a <tt>SynchronousQueue</tt> |
307 |
+ |
*/ |
308 |
|
public SynchronousQueue() {} |
309 |
|
|
310 |
|
|
311 |
< |
public void put(E x) throws InterruptedException { |
312 |
< |
doPut(x, false, 0); |
311 |
> |
/** |
312 |
> |
* Adds the specified element to this queue, waiting if necessary for |
313 |
> |
* another thread to receive it. |
314 |
> |
* @throws NullPointerException {@inheritDoc} |
315 |
> |
*/ |
316 |
> |
public void put(E o) throws InterruptedException { |
317 |
> |
doPut(o, false, 0); |
318 |
|
} |
319 |
|
|
320 |
+ |
/** |
321 |
+ |
* Adds the specified element to this queue, waiting if necessary up to the |
322 |
+ |
* specified wait time for another thread to receive it. |
323 |
+ |
* @return <tt>true</tt> if successful, or <tt>false</tt> if |
324 |
+ |
* the specified waiting time elapses before a taker appears. |
325 |
+ |
* @throws NullPointerException {@inheritDoc} |
326 |
+ |
*/ |
327 |
|
public boolean offer(E x, long timeout, TimeUnit unit) throws InterruptedException { |
328 |
|
return doPut(x, true, unit.toNanos(timeout)); |
329 |
|
} |
330 |
|
|
331 |
|
|
332 |
< |
|
332 |
> |
/** |
333 |
> |
* Retrieves and removes the head of this queue, waiting if necessary |
334 |
> |
* for another thread to insert it. |
335 |
> |
* @return the head of this queue |
336 |
> |
*/ |
337 |
|
public E take() throws InterruptedException { |
338 |
|
return doTake(false, 0); |
339 |
|
} |
340 |
|
|
341 |
+ |
/** |
342 |
+ |
* Retrieves and removes the head of this queue, waiting |
343 |
+ |
* if necessary up to the specified wait time, for another thread |
344 |
+ |
* to insert it. |
345 |
+ |
*/ |
346 |
|
public E poll(long timeout, TimeUnit unit) throws InterruptedException { |
347 |
|
return doTake(true, unit.toNanos(timeout)); |
348 |
|
} |
349 |
|
|
350 |
|
// Untimed nonblocking versions |
351 |
|
|
352 |
< |
public boolean offer(E x) { |
353 |
< |
if (x == null) throw new NullPointerException(); |
352 |
> |
/** |
353 |
> |
* Adds the specified element to this queue, if another thread is |
354 |
> |
* waiting to receive it. |
355 |
> |
* |
356 |
> |
* @throws NullpointerException {@inheritDoc} |
357 |
> |
*/ |
358 |
> |
public boolean offer(E o) { |
359 |
> |
if (o == null) throw new NullPointerException(); |
360 |
|
|
361 |
|
for (;;) { |
362 |
|
qlock.lock(); |
370 |
|
if (node == null) |
371 |
|
return false; |
372 |
|
|
373 |
< |
else if (node.set(x)) |
373 |
> |
else if (node.set(o)) |
374 |
|
return true; |
375 |
|
// else retry |
376 |
|
} |
377 |
|
} |
378 |
|
|
379 |
+ |
|
380 |
|
public E poll() { |
381 |
|
for (;;) { |
382 |
|
Node node; |
399 |
|
} |
400 |
|
} |
401 |
|
|
402 |
+ |
|
403 |
+ |
/** |
404 |
+ |
* Adds the specified element to this queue. |
405 |
+ |
* @return <tt>true</tt> (as per the general contract of |
406 |
+ |
* <tt>Collection.add</tt>). |
407 |
+ |
* |
408 |
+ |
* @throws NullPointerException {@inheritDoc} |
409 |
+ |
* @throws IllegalStateException if no thread is waiting to receive the |
410 |
+ |
* element being added |
411 |
+ |
*/ |
412 |
+ |
public boolean add(E o) { |
413 |
+ |
return super.add(o); |
414 |
+ |
} |
415 |
+ |
|
416 |
+ |
|
417 |
+ |
/** |
418 |
+ |
* Adds all of the elements in the specified collection to this queue. |
419 |
+ |
* The behavior of this operation is undefined if |
420 |
+ |
* the specified collection is modified while the operation is in |
421 |
+ |
* progress. (This implies that the behavior of this call is undefined if |
422 |
+ |
* the specified collection is this queue, and this queue is nonempty.) |
423 |
+ |
* <p> |
424 |
+ |
* This implementation iterates over the specified collection, and adds |
425 |
+ |
* each object returned by the iterator to this collection, in turn. |
426 |
+ |
* @throws NullPointerException {@inheritDoc} |
427 |
+ |
* @throws IllegalStateException if no thread is waiting to receive the |
428 |
+ |
* element being added |
429 |
+ |
*/ |
430 |
+ |
public boolean addAll(Collection<? extends E> c) { |
431 |
+ |
return super.addAll(c); |
432 |
+ |
} |
433 |
+ |
|
434 |
|
/** |
435 |
< |
* Always returns true. SynchronousQueues have no internal capacity. |
436 |
< |
* @return true. |
435 |
> |
* Always returns <tt>true</tt>. |
436 |
> |
* A <tt>SynchronousQueue</tt> has no internal capacity. |
437 |
> |
* @return <tt>true</tt> |
438 |
|
*/ |
439 |
|
public boolean isEmpty() { |
440 |
|
return true; |
441 |
|
} |
442 |
|
|
443 |
|
/** |
444 |
< |
* Always returns 0. SynchronousQueues have no internal capacity. |
444 |
> |
* Always returns zero. |
445 |
> |
* A <tt>SynchronousQueue</tt> has no internal capacity. |
446 |
|
* @return zero. |
447 |
|
*/ |
448 |
|
public int size() { |
450 |
|
} |
451 |
|
|
452 |
|
/** |
453 |
< |
* Always returns zero. SynchronousQueues have no internal capacity. |
453 |
> |
* Always returns zero. |
454 |
> |
* A <tt>SynchronousQueue</tt> has no internal capacity. |
455 |
|
* @return zero. |
456 |
|
*/ |
457 |
|
public int remainingCapacity() { |
459 |
|
} |
460 |
|
|
461 |
|
/** |
462 |
< |
* Always returns null. SynchronousQueues do not return elements |
462 |
> |
* Does nothing. |
463 |
> |
* A <tt>SynchronousQueue</tt> has no internal capacity. |
464 |
> |
*/ |
465 |
> |
public void clear() {} |
466 |
> |
|
467 |
> |
/** |
468 |
> |
* Always returns <tt>false</tt>. |
469 |
> |
* A <tt>SynchronousQueue</tt> has no internal capacity. |
470 |
> |
* @return <tt>false</tt> |
471 |
> |
*/ |
472 |
> |
public boolean contains(Object o) { |
473 |
> |
return false; |
474 |
> |
} |
475 |
> |
|
476 |
> |
/** |
477 |
> |
* Always returns <tt>false</tt>. |
478 |
> |
* A <tt>SynchronousQueue</tt> has no internal capacity. |
479 |
> |
* @return <tt>false</tt> |
480 |
> |
*/ |
481 |
> |
public boolean containsAll(Collection<? extends E> c) { |
482 |
> |
return false; |
483 |
> |
} |
484 |
> |
|
485 |
> |
/** |
486 |
> |
* Always returns <tt>false</tt>. |
487 |
> |
* A <tt>SynchronousQueue</tt> has no internal capacity. |
488 |
> |
* @return <tt>false</tt> |
489 |
> |
*/ |
490 |
> |
public boolean removeAll(Collection<? extends E> c) { |
491 |
> |
return false; |
492 |
> |
} |
493 |
> |
|
494 |
> |
/** |
495 |
> |
* Always returns <tt>false</tt>. |
496 |
> |
* A <tt>SynchronousQueue</tt> has no internal capacity. |
497 |
> |
* @return <tt>false</tt> |
498 |
> |
*/ |
499 |
> |
public boolean retainAll(Collection<? extends E> c) { |
500 |
> |
return false; |
501 |
> |
} |
502 |
> |
|
503 |
> |
/** |
504 |
> |
* Always returns <tt>null</tt>. |
505 |
> |
* A <tt>SynchronousQueue</tt> does not return elements |
506 |
|
* unless actively waited on. |
507 |
< |
* @return null. |
507 |
> |
* @return <tt>null</tt> |
508 |
|
*/ |
509 |
|
public E peek() { |
510 |
|
return null; |
524 |
|
} |
525 |
|
|
526 |
|
/** |
527 |
< |
* Returns an empty iterator. |
527 |
> |
* Returns an empty iterator: <tt>hasNext</tt> always returns |
528 |
> |
* <tt>false</tt> |
529 |
> |
* @return an empty iterator |
530 |
|
*/ |
531 |
|
public Iterator<E> iterator() { |
532 |
|
return new EmptyIterator<E>(); |
534 |
|
|
535 |
|
|
536 |
|
/** |
537 |
< |
* Returns an empty array. |
537 |
> |
* Returns a zero-length array. |
538 |
> |
* @return a zero-length array |
539 |
|
*/ |
540 |
|
public Object[] toArray() { |
541 |
|
return (E[]) new Object[0]; |
542 |
|
} |
543 |
|
|
544 |
+ |
/** |
545 |
+ |
* Sets the zeroeth element of the specified array to <tt>null</tt> |
546 |
+ |
* (if the array has non-zero length) and returns it. |
547 |
+ |
* @return the specified array |
548 |
+ |
*/ |
549 |
|
public <T> T[] toArray(T[] a) { |
550 |
|
if (a.length > 0) |
551 |
|
a[0] = null; |
552 |
|
return a; |
553 |
|
} |
554 |
|
} |
555 |
+ |
|
556 |
+ |
|
557 |
+ |
|
558 |
+ |
|
559 |
+ |
|