一个程序中有多个线程在运行,我们需要监测各个线程的运行状态,看各个线程是否已经执行完成。
如:要统计系统的各个根目录下的文件数目,一个统计线程去统计一个根目录下的文件数目。但是我们想让程序在所有统计线程统计完毕后再统一输出统计结果,这就需要用到"监视线程"模型。
下面一种"轮询"监视模型,把每一个统计类线程添加到一个队列中,用一个监视线程循环地询问队列中的线程,如果某一个线程已经执行完毕,则将它从队列中移除。
下面是统计文件的主类
import java.io.File;
/**
* 统计文件的主类
* @author XMH
*
*/
public class Manager {
/**
* @param args
*/
public static void main(String[] args) {
File[] roots = File.listRoots();//系统的根目录数组
ThreadListener tl = new ThreadListener();//监听统计文件线程的监控线程
for(int i=0;i<roots.length;i++){//根据根目录创建统计文件线程
CountFile cf = new CountFile(roots[i]);
tl.array.add(cf);
cf.start();
}
tl.start();
}
}
统计文件的线程类
/**
* 统计文件的线程类
*/
import java.io.File;
public class CountFile extends Thread {
// 根目录名
private File root;
// 标志线程是否执行完毕的属性
private boolean finished;
//要输出的信息
String info;
// 构造器,传入一个根目录名
public CountFile(File root) {
this.root = root;
}
// 查看线程是否已经执行完毕
public boolean isFinished() {
return finished;
}
// 通过线程进行文件统计
public void run() {
System.out.println(root+"盘文件统计开始");
int count = countProcess(root);
info = root.getAbsolutePath()+"盘统计文件数为"+count+"\n";
finished = true;
System.out.println(root+"盘文件统计完毕");
}
private int countProcess(File dir) {
int count = 0;
if (!dir.exists()) {// 如果该文件指向的地址不存在
return count;
}
// 将文件中的子文件保存在文件数组中
File[] files = dir.listFiles();
if (files == null) {// 如果文件数组为空,则返回0
return count;
}
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {// 如果是文件夹
count += countProcess(files[i]);
} else if (files[i].isFile()) {// 如果是标准文件
count++;
}
}
return count;
}
}
监视统计线程的线程类
/**
* 监视统计线程的线程类
*/
import java.util.ArrayList;
public class ThreadListener extends Thread{
ArrayList<CountFile> array = new ArrayList<CountFile>();
String result="";
public void run(){
boolean flag=false;
while(!flag){
for(int i=0;i<array.size();i++){
if(array.get(i).isFinished()){//判断统计文件的线程是否已经完成
result+=array.get(i).info;
array.remove(i);//将已经完成的线程对象从队列中移除
}
}
try {//每隔一定时间监听一次各个文件统计线程
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(array.size()==0){//如果统计线程都已经完成
flag=true;
System.out.println(result);
}
}
}
}