55 lines
1.6 KiB
Java
Raw Normal View History

2015-09-07 11:44:36 -06:00
// concurrency/Pool.java
2015-12-15 11:47:04 -08:00
// (c)2016 MindView LLC: see Copyright.txt
2015-11-15 15:51:35 -08:00
// We make no guarantees that this code is fit for any purpose.
// Visit http://mindviewinc.com/Books/OnJava/ for more book information.
2015-06-15 17:47:35 -07:00
// Using a Semaphore inside a Pool, to restrict
// the number of tasks that can use a resource.
import java.util.concurrent.*;
import java.util.*;
public class Pool<T> {
private int size;
private List<T> items = new ArrayList<>();
private volatile boolean[] checkedOut;
private Semaphore available;
public Pool(Class<T> classObject, int size) {
this.size = size;
checkedOut = new boolean[size];
available = new Semaphore(size, true);
// Load pool with objects that can be checked out:
for(int i = 0; i < size; ++i)
try {
2015-11-03 12:00:44 -08:00
// Assumes a no-arg constructor:
2015-06-15 17:47:35 -07:00
items.add(classObject.newInstance());
} catch(InstantiationException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public T checkOut() throws InterruptedException {
available.acquire();
return getItem();
}
public void checkIn(T x) {
if(releaseItem(x))
available.release();
}
private synchronized T getItem() {
for(int i = 0; i < size; ++i)
if(!checkedOut[i]) {
checkedOut[i] = true;
return items.get(i);
}
return null; // Semaphore prevents reaching here
}
private synchronized boolean releaseItem(T item) {
int index = items.indexOf(item);
if(index == -1) return false; // Not in the list
if(checkedOut[index]) {
checkedOut[index] = false;
return true;
}
return false; // Wasn't checked out
}
2015-09-07 11:44:36 -06:00
}