55 lines
1.6 KiB
Java
55 lines
1.6 KiB
Java
// concurrency/Pool.java
|
|
// ©2016 MindView LLC: see Copyright.txt
|
|
// We make no guarantees that this code is fit for any purpose.
|
|
// Visit http://mindviewinc.com/Books/OnJava/ for more book information.
|
|
// 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 {
|
|
// Assumes a no-arg constructor:
|
|
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
|
|
}
|
|
}
|