要想使线程成为后台线程,必须则在线程启动前调用setDaemon()方法,才能把这个线程设置为后台线程。当我们运行这个程序时候,发现没有任何结果打印到控制台,这就是因为没有非后台线程(除了main,main是一个非后台线程)使得程序保持运行。因此,程序没有打印任何信息就停止了。
好了,现在回到我们讲到的第一个实例代码,我想根据这个代码改写下,写一个测试框架,这个框架可以简化对我们遇到这种类型线程例子的测试工作。我们的watcher线程实际上是观察特定情况下监控对象内部是否违反了约束条件,对于客户而言,客户指向知道我们定义的约束条件是否被违反了,还要知道这个违反约束条件的数值是多少,如是我定义了下面的接口:
public interface InvariantState {}
这接口就是为了查看数值是否违反我们定义约束的接口,它有两个实现类:
表示成功的:
public class InvariantOK implements InvariantState { }
表示失败的:
public Object value;
public InvariantFailure(Object value)
{
this.value = value;
}
}
在InvariantFailure对象将包括一个对象,这个对象表示了有关失败原因的信息,当监控到失败情况我们就可以打印出有关失败的错误信息。
下面我们再定义一个接口,任何需要对我们定义的约束条件进行测试的类都必须要实现这个接口:
public interface Invariant {
InvariantState invariant();
}
为了防止程序因为所运行的平台(例如不同版本的windows,linux,多核系统等)对java底层技术支持的问题我们再定义一个超时类,这个类当程序在一定时间内无法正常运行时候,程序会自动终止,代码如下:
package cn.com.sxia;
import java.util.Timer;
import java.util.TimerTask;
public class Timeout extends Timer {
public Timeout(int delay,final String msg){
super(true);//设为true表明该线程是一个后台线程(Daemon)
schedule(new TimerTask() {
@Override
public void run() {
System.out.println(msg);
System.exit(0);
}
}, delay);
}
}
代码里我们继承了Timer类,在构造函数里我们调用了super(true),这个设置表明此线程将作为一个后台程序创建,前面我们讲到后台线程不会影响到非后台程序,也就是说当其他线程让程序退出时候,这个创建的Timeout对象不会干扰其他线程的运行。Timer类非常有用,java里设计它就是为了处理大量并发调度任务,下面是Timer在jdk文档里的解释: