Skip to content

Instantly share code, notes, and snippets.

@cassc
Created April 8, 2014 05:50
Show Gist options
  • Save cassc/10095260 to your computer and use it in GitHub Desktop.
Save cassc/10095260 to your computer and use it in GitHub Desktop.
Semaphore exmaple from TIJ
/*
* Semaphore example
*/
package test.another;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class TestSemaphore {
public static void main(String[] args) {
final Resc<FatEntity> resc = new Resc<FatEntity>(FatEntity.class, 20);
final List<FatEntity> fatEntities = new ArrayList<FatEntity>();
ExecutorService exec = Executors.newFixedThreadPool(10);
exec.execute(new Runnable() {
@Override
public void run() {
while(true){
try {
TimeUnit.SECONDS.sleep(2);
FatEntity f = resc.checkOut();
f.operation();
fatEntities.add(f);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
exec.execute(new Runnable() {
@Override
public void run() {
Random rand = new Random();
while(true){
try {
TimeUnit.SECONDS.sleep(3);
FatEntity f = fatEntities.get(rand.nextInt(20));
if(f!=null){
resc.checkIn(f);
}
} catch (InterruptedException e) {
// e.printStackTrace();
} catch (IndexOutOfBoundsException e){
}
}
}
});
}
static class Resc<T> {
private Semaphore available;
private List<T> items;
private int size;
private volatile boolean[] checkedOut;
public Resc(Class<T> cls,int maxCount){
this.size=maxCount;
checkedOut=new boolean[size];
available=new Semaphore(maxCount);
items = new ArrayList<T>();
for (int i=0;i<maxCount;i++) {
try {
items.add(cls.newInstance());
checkedOut[i]=false;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
public T checkOut() throws InterruptedException{
available.acquire();
return getItem();
}
public void checkIn(T item){
if(releaseItem(item)){
available.release();
}
}
private synchronized boolean releaseItem(T item) {
// Equal item may exist in items list.
int idx = items.indexOf(item);
if(idx==-1){
return false;
}
if(checkedOut[idx]){
checkedOut[idx]=false;
return true;
}
return false;
}
private synchronized T getItem() {
for(int i=0;i<size;i++){
if(!checkedOut[i]){
checkedOut[i]=true;
return items.get(i);
}
}
return null;
}
}
/*
* Object expensive to create
*/
static class FatEntity{
private volatile double d;
private static int counter=0;
private final int id = counter++;
public FatEntity(){
for(int i=1;i<10000;i++){
d+= (Math.PI+Math.E)/i;
}
}
public void operation(){
System.out.println(this);
}
@Override
public String toString() {
return "FatEntity [id=" + id + "]";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment