因此,本人認為,這個信號量類如果能返回數目,還能知道哪些對象在等待,哪些資源可使用,就非常完美了,僅僅拿到這些概括性的數字,對精確控制意義不是很大。目前還沒想到更好的用法。
下面是一個簡單例子:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* Java線程:新特征-信號量
*
* @author leizhimin
*/
public class Test {
public static void main(String[] args) {
MyPool myPool = new MyPool(20);
//創建線程池
ExecutorService threadPool = Executors.newFixedThreadPool(2);
MyThread t1 = new MyThread("任務A", myPool, 3);
MyThread t2 = new MyThread("任務B", myPool, 12);
MyThread t3 = new MyThread("任務C", myPool, 7);
//在線程池中執行任務
threadPool.execute(t1);
threadPool.execute(t2);
threadPool.execute(t3);
//關閉池
threadPool.shutdown();
}
}
/**
* 一個池
*/
class MyPool {
private Semaphore sp; //池相關的信號量
/**
* 池的大小,這個大小會傳遞給信號量
*
* @param size 池的大小
*/
MyPool(int size) {
this.sp = new Semaphore(size);
}
public Semaphore getSp() {
return sp;
}
public void setSp(Semaphore sp) {
this.sp = sp;
}
}
class MyThread extends Thread {
private String threadname; //線程的名稱
private MyPool pool; //自定義池
private int x; //申請信號量的大小
MyThread(String threadname, MyPool pool, int x) {
this.threadname = threadname;
this.pool = pool;
this.x = x;
}
public void run() {
try {
//從此信號量獲取給定數目的許可
pool.getSp().acquire(x);
//todo:也許這裡可以做更復雜的業務
System.out.println(threadname + "成功獲取了" + x + "個許可!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//釋放給定數目的許可,將其返回到信號量。
pool.getSp().release(x);
System.out.println(threadname + "釋放了" + x + "個許可!");
}
}
}
任務B成功獲取了12個許可!
任務B釋放了12個許可!
任務A成功獲取了3個許可!
任務C成功獲取了7個許可!
任務C釋放了7個許可!
任務A釋放了3個許可!
Process finished with exit code 0
從結果可以看出,信號量僅僅是對池資源進行監控,但不保證線程的安全,因此,在使用時候,應該自己控制線程的安全訪問池資源。
出處:http://lavasoft.blog.51cto.com/62575/222469