Created
April 8, 2014 05:50
-
-
Save cassc/10095260 to your computer and use it in GitHub Desktop.
Semaphore exmaple from TIJ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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