如果某个线程执行特定的操作前需要满足一定的条件,则在该条件未满足时将线程暂停运行(即暂挂线程,使其处于等待(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();
}