Advertisement
Guest User

Untitled

a guest
Aug 10th, 2011
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.94 KB | None | 0 0
  1. class AtomicReferenceBlockingPool<O> implements BlockingPool<O> {
  2.  
  3.   private final Supplier<O> supplier;
  4.   private final Semaphore semaphore;
  5.   private final List<O> objects;
  6.   private final List<Entry<O>> pool;
  7.  
  8.   AtomicReferenceBlockingPool(int capacity, Supplier<O> supplier) {
  9.     checkArgument(capacity > 0, "illegal capacity: %s; must be greater than zero", capacity);
  10.     checkNotNull(supplier, "supplier cannot be null");
  11.     this.supplier = supplier;
  12.     semaphore = new Semaphore(capacity, true);
  13.     objects = Collections.synchronizedList(Lists.<O>newArrayList());
  14.     pool = initPool(capacity);
  15.   }
  16.  
  17.   private List<Entry<O>> initPool(int capacity) {
  18.     ImmutableList.Builder<Entry<O>> builder = ImmutableList.builder();
  19.     for (int i = 0; i < capacity; i++)
  20.       builder.add(new AtomicReferenceEntry<O>());
  21.     return builder.build();
  22.   }
  23.  
  24.   @Override
  25.   public O poll() {
  26.     if (semaphore.tryAcquire())
  27.       return takeFromNextAvailable();
  28.     return null;
  29.   }
  30.  
  31.   @Override
  32.   public O take() throws InterruptedException {
  33.     semaphore.acquire();
  34.     return takeFromNextAvailable();
  35.   }
  36.  
  37.   @Override
  38.   public O take(long timeout, TimeUnit unit) throws InterruptedException {
  39.     if (semaphore.tryAcquire(timeout, unit))
  40.       return takeFromNextAvailable();
  41.     return null;
  42.   }
  43.  
  44.   private O takeFromNextAvailable() {
  45.     O object = null;
  46.     for (Iterator<Entry<O>> i = pool.iterator(); object == null;) {
  47.       Entry<O> entry = i.next();
  48.       if (entry.available())
  49.         object = entry.take();
  50.       else
  51.         object = makeAvailableAndTakeFrom(entry);
  52.     }
  53.     return object;
  54.   }
  55.  
  56.   private O makeAvailableAndTakeFrom(Entry<O> entry) {
  57.     O object = supplier.get();
  58.     objects.add(object);
  59.     entry.put(object);
  60.     return entry.take();
  61.   }
  62.  
  63.   @Override
  64.   public void put(O object) {
  65.     checkTakenFromHere(object);
  66.     putIntoNextUnavailable(object);
  67.     semaphore.release();
  68.   }
  69.  
  70.   private void putIntoNextUnavailable(O object) {
  71.     for (Entry<O> entry : pool)
  72.       if (!entry.available()) {
  73.         entry.put(object);
  74.         return;
  75.       }
  76.   }
  77.  
  78.   @Override
  79.   public void discard(O object) {
  80.     checkTakenFromHere(object);
  81.     objects.remove(object);
  82.     semaphore.release();
  83.   }
  84.  
  85.   private void checkTakenFromHere(O object) {
  86.     checkState(objects.contains(object), "%s wasn't taken from this pool", object);
  87.   }
  88.  
  89.   @Override
  90.   public Iterator<O> iterator() {
  91.     return Iterators.unmodifiableIterator(objects.iterator());
  92.   }
  93. }
  94.  
  95. class AtomicReferenceEntry<O> implements Entry<O> {
  96.  
  97.   private final AtomicReference<O> reference;
  98.  
  99.   AtomicReferenceEntry() {
  100.     reference = new AtomicReference<O>(null);
  101.   }
  102.  
  103.   @Override
  104.   public O take() {
  105.     return reference.getAndSet(null);
  106.   }
  107.  
  108.   @Override
  109.   public void put(O object) {
  110.     reference.compareAndSet(null, object);
  111.   }
  112.  
  113.   @Override
  114.   public boolean available() {
  115.     return reference.get() != null;
  116.   }
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement