因为毕业设计上需要将控制台的任务实时输出到界面上,
而且那是个Hadoop的mapreduce任务,一跑半个小时的节奏,所以需要用到多线程并随时读取返回的数据,
百度了没找到合适的方法,于是被逼无奈编写了这个十分简单的多线程操作工具类。
大概的功能就是可以执行一个特定的线程(线程必须调用本类的方法才能实现实时输出信息的功能),然后随时调用readResult方法就可以获取到结果集。
在毕业设计的应用上,就是创建一个工具类,然后让它自己去跑,根据taskId保存到session中,用ajax循环读取。
package com.imut.szd.common;import java.util.ArrayList;
import java.util.Iterator;/**
* 控制台任务类
* 本类包含一个线程,为主线程与任务线程的通讯类。
* 任务线程必须调用本类的writeResult方法才能将数据输出到本类中。
* 任务线程必须设置本类的OVER属性以确定执行结束
* 本类不宜多次执行!
* @author shizhida
*
*/
public class ConsoleTask {private ArrayList<String> resultSet;//返回结果集
private ArrayList<String> resultBuffer;//缓冲返回结果集,当LOCK的时候将数据输出到这里
private Runnable task;//执行的线程体
private String consoleTaskId;//任务ID,用于在session中查找到相应对象
public boolean LOCK;//读取锁,当主线程读取数据时先设置本参数为true,防止冲突。
public boolean OVER;//结束判断
public boolean NEW;//是否有新数据的判断,当写入时将本参数设置为true,避免无用的读取。
public ConsoleTask(String id){
LOCK = false;
OVER = false;
NEW = false;
consoleTaskId = id;
resultSet = new ArrayList<String>();
resultBuffer = new ArrayList<String>();}
public void start(){
new Thread(task).start();
}
public Runnable getTask() {
return task;
}public void setTask(Runnable task) {
this.task = task;
}public String getConsoleTaskId() {
return consoleTaskId;
}public void setConsoleTaskId(String consoleTaskId) {
this.consoleTaskId = consoleTaskId;
}/**
* 读取结果集的操作。
* @return
*/
public String[] readResult(){
LOCK = true;//设置读取锁
String[] result = new String[resultSet.size()];//创建返回值
for(int i=0;i<result.length;i++){
result[i] = resultSet.get(i);
}
resultSet.clear();//清空结果集
NEW = false;//声明没有新结果
LOCK = false;//解锁
return result;
}
/**
*写入结果集的操作
**/
public void writeResult(String res){
if(!LOCK)//判断是否有锁,无锁执行以下代码:
{
//将缓冲结果集的数据转移到结果集中
if(resultBuffer.size()!=0)
{
Iterator<String> iter = resultBuffer.iterator();
while(iter.hasNext()){
resultSet.add(iter.next());
}
resultBuffer.clear();
}
//向结果集输出数据
resultSet.add(res);
}
//若已上锁,向缓冲结果集输出数据
else resultBuffer.add(res);
NEW = true;//声明新结果存在
}public void destory(){
System.out.println("ConsoleTask "+consoleTaskId+"has been destory!");
//SessionOperation.remove(this.getConsoleTaskId());
this.OVER = true;
}
}
实现的很粗糙。但总算是实现了需要的功能,给自己赞一个~