保护性暂挂模式(Guarded Suspension)

1、核心思想
如果某个线程执行特定的操作前需要满足一定的条件,则在该条件未满足时将线程暂停运行(即暂挂线程,使其处于等待(waiting)状态,直到该条件满足时才继续运行)
2、评价与实现考量
a、GuardedAction call方法采用闭包方式,会增加JVM垃圾回收的负担。
b、可能增加上下文切换,过多则会消耗系统的CPU,从而降低系统处理能力。
c、内存可见性和锁泄露, 可改变的状态要用volatile关键字修饰,lock.unlock()语句一定要放在finally语句里面执行。
3、可复用代码
Predicate、GuardedAction、Blocker、ConditionVarBlocker类
4、参考网站
Runnable、Callable、Future、FutureTask这几个与线程相关的类或者接口
学习地址:http://blog.csdn.net/bboyfeiyu/article/details/24851847

定时任务:Java中Timer和TimerTask的使用
学习地址:http://batitan.iteye.com/blog/253483

Condition与Lock一起使用,相当于线程中的wait()/notify()/notifyAll()
学习地址:http://blog.csdn.net/heyutao007/article/details/49889849

lock与lockInterruptibly的区别

学习地址:http://suo.iteye.com/blog/1331312


public interface Predicate {
public boolean evaluate();
}

public abstract class GuardedAction<V> implements Callable<V> {
protected final Predicate guard;

public GuardedAction(Predicate guard) {
this.guard = guard;
}
}


public interface Blocker {

/**
* 在保护条件成立时执行目标动作;否则阻塞当前线程,直到保护条件成立
* @param guardedAction 带保护条件的目标动作
* @return
* @throws Exception
*/
public <V> V callWithGuard(GuardedAction<V> guardedAction) throws Exception;

/**
* 执行stateOperation所指定的操作后,决定是否唤醒本Blocker所暂挂的所有线程中的一个线程
* @param stateOperation、
* 更改状态的操作,其call方法的返回值为true时,该方法才会唤醒被暂挂的线程
* @throws Exception
*/
public void singleAfter(Callable<Boolean> stateOperation) throws Exception;

public void single() throws InterruptedException;

/**
* 执行stateOperation所指定的操作后,决定是否唤醒本Blocker所暂挂的所有线程
* @param stateOperation
* 更改状态的操作,其call方法的返回值为true时,该方法才会唤醒被暂挂的线程
* @throws Exception
*/
public void broadcastAfter(Callable<Boolean> stateOperation) throws Exception;
}


public class ConditionVarBlocker implements Blocker {
private final Lock lock;
private final Condition condition;

public ConditionVarBlocker() {
this.lock = new ReentrantLock();
this.condition = lock.newCondition();
}

public ConditionVarBlocker(Lock lock) {
this.lock = lock;
this.condition = lock.newCondition();
}

@Override
public <V> V callWithGuard(GuardedAction<V> guardedAction) throws Exception {
lock.lockInterruptibly();
try {
V result;
final Predicate guard = guardedAction.guard;
while(!guard.evaluate()){
condition.await();
}
result = guardedAction.call();
return result;
} finally{
lock.unlock();
}
}

@Override
public void singleAfter(Callable<Boolean> stateOperation) throws Exception {
lock.lockInterruptibly();
try {
if(stateOperation.call()){
condition.signal();
}
} finally{
lock.unlock();
}
}

@Override
public void single() throws InterruptedException {
lock.lockInterruptibly();
try {
condition.signal();
} finally{
lock.unlock();
}
}

@Override
public void broadcastAfter(Callable<Boolean> stateOperation) throws Exception {
lock.lockInterruptibly();
try {
if(stateOperation.call()){
condition.signalAll();
}
} finally{
lock.unlock();
}
}
}


/**
 * 负责连接告警服务器,并发送告警信息至告警服务器
 */
public class AlarmAgent {
//用于记录是否连接上告警服务器
private volatile boolean connectedToServer = false;

private volatile Predicate agentConnected = new Predicate() {
@Override
public boolean evaluate() {
return connectedToServer;
}
};

private final Blocker blocker = new ConditionVarBlocker();

//心跳定时器
private final Timer heartbeatTimer = new Timer(true);

/**
* 发送告警信息
* @param alarm 告警信息
* @throws Exception
*/
public void sendAlarm(final AlarmInfo alarm) throws Exception{
GuardedAction<Void> guardedAction = new GuardedAction<Void>(agentConnected) {
@Override
public Void call() throws Exception {
doSendAlarm(alarm);
return null;
}
};

blocker.callWithGuard(guardedAction);
}

private void doSendAlarm(AlarmInfo alarm) {
System.out.println("sending alarm " + alarm.toString());

try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}

public void init(){
Thread connectingThread = new Thread(new ConnectingTask());
connectingThread.start();

//schedule(TimerTask task, long delay, long period)
heartbeatTimer.schedule(new HeartbeatTask(), 60000, 20);
}

protected void disConnected() {
System.out.println("disconneccted from alarm server");
connectedToServer = false;
}

protected void onConnected() {
try {
blocker.broadcastAfter(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
connectedToServer = true;
System.out.println("connected to alarm server");
return Boolean.TRUE;
}
});
} catch (Exception e) {
e.printStackTrace();
}
}

//负责与告警服务器建立网络连接
private class ConnectingTask implements Runnable{
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
onConnected();
}
}

private class HeartbeatTask extends TimerTask{
@Override
public void run() {
if(!testConnection()){
onDisConnected();
reconnect();
}
}

private void reconnect() {
ConnectingTask thread = new ConnectingTask();
//直接在心跳任务器中执行
thread.run();
}

private void onDisConnected() {
// TODO Auto-generated method stub

}

private boolean testConnection() {
return true;
}
}
}


public static void main(String[] args) {
AlarmAgent agent = new AlarmAgent();
new Thread(){
public void run() {
try {
for(int i=0; i<100; i++){
agent.sendAlarm(new AlarmInfo());
}
} catch (Exception e) {
}
};
}.start();

new Thread(){
public void run() {
try {
agent.init();
} catch (Exception e) {
}
};
}.start();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值