View Javadoc

1   /**
2    * Copyright 2008 Atlassian Pty Ltd 
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); 
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at 
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0 
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  
17  package com.atlassian.util.concurrent;
18  
19  import net.jcip.annotations.ThreadSafe;
20  
21  import java.lang.ref.WeakReference;
22  import java.util.Iterator;
23  import java.util.NoSuchElementException;
24  import java.util.Queue;
25  import java.util.concurrent.LinkedBlockingQueue;
26  
27  /**
28   * Simple {@link Iterable} that holds {@link WeakReference weak references} to content elements. For
29   * convenience there are {@link #add(Object)} and {@link #isEmpty()} methods.
30   * <p>
31   * {@link Iterator Iterators} returned by this object maintain a hard reference to the next object.
32   * They are otherwise unstable as references may be garbage collected at any time
33   */
34  @ThreadSafe public class WeakIterable<E> implements Iterable<E> {
35      private final Queue<WeakReference<E>> queue = new LinkedBlockingQueue<WeakReference<E>>();
36  
37      E add(final E e) {
38          queue.add(new WeakReference<E>(e));
39          return e;
40      }
41  
42      boolean isEmpty() {
43          return !iterator().hasNext();
44      }
45  
46      public Iterator<E> iterator() {
47          final Iterator<WeakReference<E>> iterator = queue.iterator();
48          return new Iterator<E>() {
49              E next = getNext();
50  
51              public boolean hasNext() {
52                  return next != null;
53              }
54  
55              public E next() {
56                  if (next == null) {
57                      throw new NoSuchElementException();
58                  }
59                  try {
60                      return next;
61                  }
62                  finally {
63                      next = getNext();
64                  }
65              }
66  
67              public void remove() {
68                  throw new UnsupportedOperationException();
69              }
70  
71              E getNext() {
72                  E result = null;
73                  while (result == null) {
74                      if (!iterator.hasNext()) {
75                          return null;
76                      }
77                      final WeakReference<E> ref = iterator.next();
78                      final E e = ref.get();
79                      if (e == null) {
80                          iterator.remove();
81                          continue;
82                      }
83                      result = e;
84                  }
85                  return result;
86              }
87          };
88      }
89  }