Pool.java 类
package com.xyw.concurrent.blog;
import java.util.*;
import java.util.concurrent.*;
/*
* 对象池概念.管理和回收对象,可以签出和签入对象的概念
*/
public class Pool<T> {
private int size;
private List<T> items = new ArrayList<T>();
private volatile boolean[] checkedOut;
private Semaphore available; // 计数信号量 允许n个任务同时访问这个资源
public Pool(Class<T> classObject, int size){
this.size = size;
checkedOut = new boolean[size]; // 用来表示某个任务是否被签出的情况
available = new Semaphore(size, true);
for(int i = 0; i < size; ++i){
try{
items.add(classObject.newInstance()); // 现在向其中添加对象
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
public T checkOut() throws InterruptedException{
available.acquire();
return getItem(); // 对象签出对象池,这个是重新获得一个可用的对象从对象池中获得
}
public void checkIn(T x){
if(releaseItem(x)){
available.release(); // 对象签入对象池,用于回收对象池
// 而 semaphore 的真正起到的作用 ,只是 利用并发,进行技术信号量
}
}
private synchronized T getItem(){
for(int i =0; i< size; ++i){
if(!checkedOut[i]){
checkedOut[i] = true;
return items.get(i);
}
}
return null;
}
private synchronized boolean releaseItem(T item){
int index = items.indexOf(item);
if (index == -1) return false;
if (checkedOut[index]){
checkedOut[index] = false;
return true;
}
return false; // 这个表示,没有被签出的情况
}
}
Fat.java 类
package com.xyw.concurrent.blog;
public class Fat {
private volatile double d;
private static int counter = 0;
private final int id = counter++;
public Fat(){
for(int i = 1; i < 10000; i++){
d += (Math.PI + Math.E) / (double) i;
}
}
public void operation(){
System.out.println(this);
}
public String toString(){
return "Fat id:" + id;
}
} // 这是个创建代价高昂的对象类型,其构造器运行起来很是费事
SemaphoreDemo.java
package com.xyw.concurrent.blog;
import java.util.*;
import java.util.concurrent.*;
class CheckoutTask<T> implements Runnable{
private static int counter = 0;
private final int id = counter++;
private Pool<T> pool;
public CheckoutTask(Pool<T> pool){
this.pool = pool; // 创建的对象池,用于回收线程和产生线程
}
public void run(){
try{
T item = pool.checkOut(); // 签出一个线程
System.out.println(this +"checked out" + item); // 产生出一个线程
TimeUnit.SECONDS.sleep(1); // 产生一个对象,并运行一段时间
System.out.println(this + "checking in " + item);
pool.checkIn(item); // 回收对象,到对象池里面
}catch(InterruptedException e){
}
}
public String toString(){
return "CheckedOutTask" + id + " ";
}
}
public class SemaphoreDemo {
final static int SIZE = 25;
public static void main(String[] args) throws Exception{
final Pool<Fat> pool = new Pool<Fat>(Fat.class,SIZE); // 创建对象池对象
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < SIZE; i++){
exec.execute(new CheckoutTask<Fat>(pool));
}
System.out.println("All CheckoutTasks created");
List<Fat> list = new ArrayList<Fat>();
for(int i = 0; i< SIZE; i++){
Fat f = pool.checkOut();
System.out.println(i + " main() thread checked out");
f.operation();
list.add(f);
}
Future<?> blocked = exec.submit(new Runnable(){
public void run(){
try{
pool.checkOut();
}catch(InterruptedException e){
System.out.println("checkOut() Interrupted");
}
}
}); // 一旦池中对象都被签出,Semaphore 将不再允许执行任何签出操作 block 的方法被Pool忽略。
TimeUnit.SECONDS.sleep(2);
blocked.cancel(true);
System.out.println("checking in objects in" + list);
for(Fat f : list)
pool.checkIn(f);
for(Fat f: list)
pool.checkIn(f);
exec.shutdown();
}
}
运行结果:
CheckedOutTask0 checked outFat id:0
CheckedOutTask2 checked outFat id:2
CheckedOutTask1 checked outFat id:1
CheckedOutTask3 checked outFat id:3
CheckedOutTask4 checked outFat id:4
CheckedOutTask5 checked outFat id:5
CheckedOutTask6 checked outFat id:6
CheckedOutTask7 checked outFat id:7
CheckedOutTask8 checked outFat id:8
CheckedOutTask9 checked outFat id:9
CheckedOutTask10 checked outFat id:10
CheckedOutTask11 checked outFat id:11
CheckedOutTask12 checked outFat id:12
CheckedOutTask13 checked outFat id:13
CheckedOutTask14 checked outFat id:14
CheckedOutTask15 checked outFat id:15
CheckedOutTask16 checked outFat id:16
CheckedOutTask17 checked outFat id:17
CheckedOutTask18 checked outFat id:18
CheckedOutTask19 checked outFat id:19
CheckedOutTask20 checked outFat id:20
CheckedOutTask21 checked outFat id:21
CheckedOutTask22 checked outFat id:22
All CheckoutTasks created
CheckedOutTask23 checked outFat id:23
0 main() thread checked out
Fat id:24
CheckedOutTask2 checking in Fat id:2
CheckedOutTask5 checking in Fat id:5
CheckedOutTask24 checked outFat id:2
CheckedOutTask4 checking in Fat id:4
CheckedOutTask7 checking in Fat id:7
CheckedOutTask3 checking in Fat id:3
CheckedOutTask1 checking in Fat id:1
CheckedOutTask0 checking in Fat id:0
CheckedOutTask9 checking in Fat id:9
CheckedOutTask8 checking in Fat id:8
1 main() thread checked out
Fat id:5
CheckedOutTask11 checking in Fat id:11
CheckedOutTask6 checking in Fat id:6
2 main() thread checked out
Fat id:0
CheckedOutTask10 checking in Fat id:10
3 main() thread checked out
CheckedOutTask13 checking in Fat id:13
CheckedOutTask12 checking in Fat id:12
CheckedOutTask14 checking in Fat id:14
Fat id:1
4 main() thread checked out
Fat id:3
5 main() thread checked out
Fat id:4
6 main() thread checked out
Fat id:6
7 main() thread checked out
Fat id:7
8 main() thread checked out
Fat id:8
CheckedOutTask15 checking in Fat id:15
CheckedOutTask16 checking in Fat id:16
CheckedOutTask21 checking in Fat id:21
CheckedOutTask20 checking in Fat id:20
CheckedOutTask19 checking in Fat id:19
CheckedOutTask22 checking in Fat id:22
CheckedOutTask18 checking in Fat id:18
CheckedOutTask17 checking in Fat id:17
9 main() thread checked out
CheckedOutTask23 checking in Fat id:23
Fat id:9
10 main() thread checked out
Fat id:10
11 main() thread checked out
Fat id:11
12 main() thread checked out
Fat id:12
13 main() thread checked out
Fat id:13
14 main() thread checked out
Fat id:14
15 main() thread checked out
Fat id:15
16 main() thread checked out
Fat id:16
17 main() thread checked out
Fat id:17
18 main() thread checked out
Fat id:18
19 main() thread checked out
Fat id:19
20 main() thread checked out
Fat id:20
21 main() thread checked out
Fat id:21
22 main() thread checked out
Fat id:22
23 main() thread checked out
Fat id:23
CheckedOutTask24 checking in Fat id:2
24 main() thread checked out
Fat id:2
checkOut() Interrupted
checking in objects in[Fat id:24, Fat id:5, Fat id:0, Fat id:1, Fat id:3, Fat id:4, Fat id:6, Fat id:7, Fat id:8, Fat id:9, Fat id:10, Fat id:11, Fat id:12, Fat id:13, Fat id:14, Fat id:15, Fat id:16, Fat id:17, Fat id:18, Fat id:19, Fat id:20, Fat id:21, Fat id:22, Fat id:23, Fat id:2]