前段时间开发短信收发系统,遇到一个问题,就是有n个对象都可以通过Mobile对象发短信,但同一时刻只允许一个对象进行操作。所以设计了一个客户限制管理器的对象来解决,但由于种种原因没有用到实际系统中。后来经过仔细考虑,发现它不仅可以用于端口的管理,还可用于其他需要针对客户访问数量进行限制的各种服务中去。—-这里的“客户”是指要操作该管理器的对象
/**
* 客户限制管理器的抽象类
* 此抽象类实现了对客户访问的限制,当一个客户访问该服务时,可以通过halt(long guestid)方法阻止其他客户进行
* 访问,防止多个客户同时访问产生的冲突。例如:对通讯端口的访问等。
*/
public abstract class GuestManager {
/**
* 时间:一分钟
*/
protected static final long ONE_MINUTE = 60L * 1000L;
/**
* 时间:一小时
*/
protected static final long ONE_HOUR = 60L * ONE_MINUTE;
/**
* 自动清理客户记录的间隔时间
*/
private long cleanInterval;
/**
* 客户记录
*/
private Hashtable guests;
/**
* 当前限制的客户
*/
private long limitGuest;
/**
* 自动清除过期客户的线程
*/
private Thread autoCleanThread;
/**
* 客户注册
*
* @return 返回分配给客户端的唯一标识,如果注册失败,返回-1
*/
public long login() {
long guestid = -1L;
// 增加客户记录
Hashtable guests = getGuests();
if (guests != null) {
guestid = System.currentTimeMillis();
guests.put(“” + guestid, “” + guestid);
update(guestid);
// if (guests.size() == 1)
// connect();
}
return guestid;
}
/**
* 检查客户是否已经注册
*
* @param guestid
* 客户标识
* @return 如果客户已经注册返回true,否则返回false
*/
public boolean isLogin(long guestid) {
boolean flag = false;
if (guestid > 0) {
Hashtable guests = getGuests();
if (guests != null)
flag = guests.containsKey(“” + guestid);
if (flag)
update(guestid);
}// end if (guestid > 0)
return flag;
}
/**
* 注销客户
* 如果仍有其他客户在使用此对象,则仅仅注销guestid客户,否则调用disconnect()方法关闭连接。
*
* @param guestid
* 客户标识
* @return 返回是否成功注销
*/
public void logout(long guestid) {
Hashtable guests = getGuests();
if (guests != null) {
if (guestid > 0 && guests.containsKey(“” + guestid)) {
guests.remove(“” + guestid);
}// end if (guestid > 0 && getGuests().containsKey(“” +
// guestid))
}// end if (guests != null)
}
/**
* 限制
* 如果某一客户调用了该方法,那么其他客户将无法访问,直至该客户调用resume()释放。
*
* @param guestid
* 中断标识
* @return 返回是否成功中断
*/
public boolean limit(long guestid) {
boolean flag = false;
if (isLogin(guestid)) {
update(guestid);
if (isLimit(guestid))
return flag;
limitGuest = guestid;
flag = true;
}// end if (isLogin(guestid))
return flag;
}
/**
* 释放
*
* @param guestid
* 客户标识
* @return 返回是否释放成功
*/
public boolean resume(long guestid) {
boolean flag = false;
if (isLogin(guestid)) {
update(guestid);
if (limitGuest == guestid) {
limitGuest = -1L;
}// end if(haltGuest == guestid)
flag = !isLimit();
}
return flag;
}
/**
* 是否限制其他客户调用
*
* @return 返回是否限制其他客户调用
*/
protected boolean isLimit() {
boolean flag = false;
if (limitGuest > 0) {
long lasttime = Long.parseLong((getGuests().get(
“” + limitGuest)));
if (lasttime > 0) {
// 如果10分钟内无响应,则注释放该客户的中断
long time = System.currentTimeMillis() – 10L
* ONE_MINUTE;
if (time < lasttime)
flag = true;
else
limitGuest = -1;
}
}// end if(this.id <= 0)
return flag;
}
/**
* 该客户是否被限制访问
*
* @param haltId
* 客户标识
* @return 返回true表示禁止访问,false表示可以访问
*/
public boolean isLimit(long guestid) {
boolean flag = true;
if (isLogin(guestid)) {
update(guestid);
flag = isLimit();
if (flag) {
if (guestid > 0 && limitGuest == guestid)
flag = false;
}// end if(flag)
}
return flag;
}
/**
* 取得当前限制客户的标识(该标识是该管理器为客户分配的一个唯一标识)
*
* @return 返回当前限制客户的标识
*/
protected long getLimitGuest() {
return limitGuest;
}
/**
* 更新客户最近使用时间
*
* @param guestid
* 客户标识
*/
protected void update(long guestid) {
runThread();
Hashtable guests = getGuests();
if (guests != null && guests.containsKey(“” + guestid))
guests.put(“” + guestid, “”
+ System.currentTimeMillis());
}
/**
* 运行监听线程
*/
protected void runThread() {
// 客户自动清理线程
if (autoCleanThread != null && !autoCleanThread.isAlive())
autoCleanThread = null;
if (autoCleanThread == null) {
autoCleanThread = new AutoCleanThread();
autoCleanThread.start();
}// end if (autoCleanThread == null)
}
/**
* 设置自动清理客户记录的间隔时间
*
* @param time
* 间隔时间(毫秒)
*/
public void setCleanInterval(long time) {
if (time > 0)
cleanInterval = time;
}
/**
* 取得自动清理客户记录的间隔时间
*
* @return 返回自动清理客户记录的间隔时间(毫秒)
*/
public long getCleanInterval() {
return cleanInterval;
}
/**
* 取得客户记录
*
* @return 返回客户记录。格式为
*/
protected Hashtable getGuests() {
if (guests == null)
guests = new Hashtable();
return guests;
}
/**
* 输出错误信息
*
* @param err
*/
public abstract void trace(String err);
/**
* 自动清除超时的客户端的线程
*
*/
private class AutoCleanThread extends Thread {
public void run() {
trace(“AutoCleanThread thread start runing…”);
long interval = ONE_HOUR / 4L;
if (getCleanInterval() > 0)
interval = getCleanInterval();
while (autoCleanThread == this && getGuests().size() > 0) {
long time = System.currentTimeMillis()
– ONE_HOUR / 2L;
Enumeration keys = getGuests().keys();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
if (key != null) {
long lasttime = Long.parseLong(getGuests()
.get(key));
if (time > lasttime)
// 超时
getGuests().remove(key);
}// end if (key != null)
}// end while (keys.hasMoreElements())
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
e.printStackTrace();
trace(“error – ” + e.toString());
}
}// end while (mobiles != null && mobiles.size() > 0)
trace(“AutoCleanThread thread end…”);
}
}
}
/**
* 通讯端口的客户端限制管理器的抽象类
* 该类继承自GuestManager类,增加了connect()、disconnect()等方法
*
* @author none
*
*/
public abstract class PortGuestManager extends GuestManager {
/**
* 连接
*
* @return 返回是否连接成功
*/
protected abstract boolean connect();
/**
* 断开
*
* @return 返回是否断开成功
*/
protected abstract boolean disconnect();
/**
* 是否已经连接
*
* @return 返回端口是否已经连接
*/
protected abstract boolean isConnected();
public long login() {
long guestid = -1L;
if (!isConnected())
connect();
if (isConnected())
guestid = super.login();
return guestid;
}
public boolean limit(long guestid) {
boolean flag = false;
if (isConnected())
flag = super.limit(guestid);
return flag;
}
public void logout(long guestid) {
super.logout(guestid);
Hashtable guests = getGuests();
if (guests != null)
if (guests.size() <= 0)
disconnect();
}
public boolean isLimit(long guestid) {
boolean flag = true;
if (isConnected())
flag = super.isLimit(guestid);
return flag;
}
}
一起交流学习请访问:Tore_m_1206686_21115_1_1.html”>http://www.shangxueba.com/sTore_m_1206686_21115_1_1.html
最可怕的敌人,就是没有坚强的信念。