package com.chinasofti.javase;
import java.util.Random;
import java.util.Vector;
public class Semaphore {
// 用於存放信號量鎖的隊列
private Vector locks = new Vector();
// 通行信號量的數量
private int permitNum = 1;
// 目前可用的通行信號量的數量
private int nowPermitNum = 1;
// 通行信號量是否允許你增長
private boolean permitNumGrow = false;
// 信號量放行時是否遵循公平原則
private boolean fair = false;
// 不遵循公平原則時放行的隨機工具
Random random = new Random();
public Semaphore(int permitNum,boolean permitNumGrow,boolean fair){
this.permitNum=permitNum;
this.nowPermitNum=permitNum;
this.permitNumGrow=permitNumGrow;
this.fair=fair;
}
public Semaphore(int permitNum,boolean fair){
this(permitNum,true,fair);
}
public Semaphore(int permitNum){
this(permitNum,false);
}
public Semaphore(){
this(0);
}
// 消費者希望從信號量中獲取一個信號許可,如果目前仍然存在可用許可,則消費者順利執行,否則消費者線程阻塞等待,知道生產者生產資源,產生新的許可
public void acquire() {
//如果當前信號量許可大於0,表示消費者可以直接操作資源
if (nowPermitNum > 0) {
//本消費者操作資源後許可數減1
nowPermitNum--;
} else {
//如果目前無可用的信號量許可,則創建一個新的線程鎖(任意Java對象均可作爲線程鎖存在)
Object lock = new Object();
//將當前創建的線程鎖加入到線程鎖列表中
locks.add(lock);
//利用當前的線程鎖鎖定當前消費者線程
synchronized (lock) {
try {
//阻塞當前線程
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
// 生產者已經生產了新的可供消費資源,向信號量中增加一個可用許可
public void release() {
//目前正在有消費者等待資源
if(locks.size()>0){
//放行的消費者編號
int index=0;
//如果規定爲非公平原則
if(!fair){
//隨機取出現有的消費者編號
index=Math.abs(random.nextInt())%locks.size();
}
Object lock=locks.get(index);
locks.remove(index);
synchronized (lock) {
//喚醒對應的消費者線程
lock.notify();
}
}
//如果條件滿足則增加可用許可量
else if(permitNumGrow||nowPermitNum<permitNum){
nowPermitNum++;
}
}
}
信號量代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.