一切都准备好了,我们创建用于进行监控的完美类了,代码如下:
package cn.com.sxia;public class
InvariantWatcher extends Thread {
private Invariant invariant;
public InvariantWatcher(Invariant invariant){
this.invariant = invariant; setDaemon(true);
start();
}
public InvariantWatcher(Invariant invariant,final int timeout){
this(invariant);
new Timeout(timeout, "超时了....");
}
public void run(){
while(true){
InvariantState state = invariant.invariant();
if (state instanceof InvariantFailure){
System.out.println("Invariant violated: " + ((InvariantFailure)state).value);
System.exit(0);
}
}
}
}
InvariantWatcher extends Thread {
private Invariant invariant;
public InvariantWatcher(Invariant invariant){
this.invariant = invariant; setDaemon(true);
start();
}
public InvariantWatcher(Invariant invariant,final int timeout){
this(invariant);
new Timeout(timeout, "超时了....");
}
public void run(){
while(true){
InvariantState state = invariant.invariant();
if (state instanceof InvariantFailure){
System.out.println("Invariant violated: " + ((InvariantFailure)state).value);
System.exit(0);
}
}
}
}
InvariantWatcher类就是我们定义好的监控类,InvariantWatcher类里我定义了两个构造函数,第一个构造函数接受一个要测试的Invariant对象的引用作为参数,然后启动线程。第二个构造函数调用第一个构造函数,然后创建一个Timeout,用来在一定的时间延迟之后终止所有的线程。
特别注意:我们不能再线程里抛出异常,因为这只会终止线程而不会终止程序,所以我都是写的是System.exit(0);
下面我们将我们的个实例代码修改下,代码如下:
package cn.com.sxia;
public class EvenGenerator implements Invariant {
private int i;
public void next(){
i++;
i++;
}
public int getValue(){
return i;
}
@Override
public InvariantState invariant() {
int val = i;
if (val % 2 == 0)
return new InvariantOK();
else
return new InvariantFailure(new Integer(val));
}
public static void main(String[] args){
EvenGenerator gen = new EvenGenerator();
new InvariantWatcher(gen);
while(true){
gen.next();
}
}
}
我们为学习共享资源的java线程问题所设计的监控测试框架已经完成了,或许有些人可能不太明白为啥要这么设计,没事,先把代码在eclipse里跑跑就会有点感觉了,我们接着往下看了。
我们先从理论开始,共享资源的线程难题到底是啥呢?我们还是套用用笔的例子,有一支笔,两个人同时都要使用它,结果是两个人争执不下,最后谁都没用到这支笔,大家都苦耗在哪里。
因此我们应该在使用多线程时候避免这样的事情的发生,要防止这样问题的发生,只要在线程使用资源的时候给它加一把锁就行了。那么情形就会变成这样,访问该资源的第一个线程给资源加锁后,其他线程只能等待第一个线程把锁解开才能访问资源,锁解除的同时另外一个线程就可以对该资源加锁并且进行访问了。