信號量代碼

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++;			
		}
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章