调用方法:
/**
* 点击量/月(年)callable
*/
public void yearlyclickcallable() {
// 获取参数
string year = getpara("year");
// 统计数据集x
list<string> xlist = new arraylist<string>();
xlist.add("january");
xlist.add("february");
xlist.add("march");
xlist.add("april");
xlist.add("may");
xlist.add("june");
xlist.add("july");
xlist.add("august");
xlist.add("september");
xlist.add("october");
xlist.add("november");
xlist.add("december");
// 统计数据集y
list<integer> ylist = new arraylist<integer>();
// 接收线程值
list<future<list<map<string, object>>>> futurelist = new arraylist<future<list<map<string, object>>>>();
// 计数器
int count = 0;
// 创建一个线程池(决定开启几个线程)
executorservice pool = executors.newcachedthreadpool();
// 每月的日志分析
for (int m = 1; m <= 12; m++) {
// 收集日期参数
list<string> datelist = new arraylist<string>();
//
string date = "";
// 判断有多少天
int days = calendarutil.weekformonth(integer.valueof(year), m);
// 组合日期
for (int i = 1; i <= days; i++) {
if (i <= 9) {
if (m <= 9) {
date = year + "-0" + m + "-0" + i;
} else {
date = year + "-" + m + "-0" + i;
}
} else {
if (m <= 9) {
date = year + "-0" + m + "-" + i;
} else {
date = year + "-" + m + "-" + i;
}
}
datelist.add(date);
}
// 启动
future<list<map<string, object>>> future = pool.submit(new readlogfilecallablebyyear(datelist));
futurelist.add(future);
}
// 关闭线程池
pool.shutdown();
// 接收结果集
for (future<list<map<string, object>>> future : futurelist) {
try {
// 接收参数
list<map<string, object>> list = future.get(1, timeunit.seconds);
// 设置参数
for (int p = 0; p < list.size(); p++) {
count += (int) list.get(p).get("clickcount");
if (list.get(p).get("month").equals("01")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("02")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("03")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("04")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("05")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("06")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("07")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("08")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("09")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("10")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("11")) {
ylist.add((integer) list.get(p).get("clickcount"));
} else if (list.get(p).get("month").equals("12")) {
ylist.add((integer) list.get(p).get("clickcount"));
}
}
} catch (exception e) {
e.printstacktrace();
}
}
setattr("totalcount", count);
setattr("x", xlist);
setattr("y", ylist);
renderjson();
}
多线程方法:
package com.ninemax.util.loganalysis;
import java.io.bufferedreader;
import java.io.file;
import java.io.fileinputstream;
import java.io.ioexception;
import java.io.inputstreamreader;
import java.util.arraylist;
import java.util.hashmap;
import java.util.list;
import java.util.map;
import java.util.concurrent.callable;
import com.ninemax.util.loganalysis.tool.constantutil;
/**
* 多线程有返回值
*
* @author darker
*
*/
public class readlogfilecallablebyyear implements callable<list<map<string, object>>> {
// 日期数组
private list<string> clickdate;
// 返回结果集
public list<map<string, object>> list = new arraylist<map<string, object>>();
public readlogfilecallablebyyear(list<string> clickdate) {
this.clickdate = clickdate;
}
@override
public list<map<string, object>> call() throws exception {
// 接收参数
map<string, object> map = new hashmap<string, object>();
// 利用fileinputstream读取文件信息
fileinputstream fis = null;
// 利用inputstreamreader进行转码
inputstreamreader reader = null;
// 利用bufferedreader进行缓冲
bufferedreader bufreader = null;
// 利用stringbuffer接收文件内容容器
stringbuffer buf = new stringbuffer();
// 点击量/月
int monthclick = 0;
for (int i = 0; i < clickdate.size(); i++) {
// 获取文件
file clicklogfile = new file(constantutil.loglocation, "article.click."+ clickdate.get(i) + ".txt");
// 判断文件是否存在
if (!clicklogfile.exists() || clicklogfile.isdirectory()) {
system.err.println(clickdate.get(i) + "的文件不存在...");
map.put("month", clickdate.get(i).substring(5, 7));
map.put("clickcount", 0);
list.add(map);
return list;
} else {
try {
// 节点流
fis = new fileinputstream(clicklogfile);
// 转换流
reader = new inputstreamreader(fis, "utf-8");
// 处理流
bufreader = new bufferedreader(reader);
// 计数器
int count = 0;
// 按行读取
string line = "";
// 读取文件
while ((line = bufreader.readline()) != null) {
// 计数
count++;
// 接收数据
if (!line.equals(null) && !line.equals("")) {
buf.append(line + "\n");
}
}
if (count == 0) {
count = 0;
} else {
count = count - 1;
}
monthclick += count;
} catch (exception e) {
e.printstacktrace();
} finally {
// 关闭流
try {
bufreader.close();
reader.close();
fis.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
}
}
// 结果集
map.put("month", clickdate.get(0).substring(5, 7));
if (monthclick == 0) {
map.put("clickcount", 0);
} else {
map.put("clickcount", monthclick);
}
list.add(map);
return list;
}
}
再给大家分享一个网友的实例,也非常的不错
import java.util.concurrent.callable;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
import java.util.concurrent.future;
/**
* callable 和 future接口
* callable是类似于runnable的接口,实现callable接口的类和实现runnable的类都是可被其它线程执行的任务。
* callable和runnable有几点不同:
* (1)callable规定的方法是call(),而runnable规定的方法是run().
* (2)callable的任务执行后可返回值,而runnable的任务是不能返回值的。
* (3)call()方法可抛出异常,而run()方法是不能抛出异常的。
* (4)运行callable任务可拿到一个future对象, future表示异步计算的结果。
* 它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
* 通过future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
*/
public class callableandfuture {
/**
* 自定义一个任务类,实现callable接口
*/
public static class mycallableclass implements callable {
// 标志位
private int flag = 0;
public mycallableclass(int flag) {
this.flag = flag;
}
public string call() throws exception {
if (this.flag == 0) {
// 如果flag的值为0,则立即返回
return "flag = 0";
}
if (this.flag == 1) {
// 如果flag的值为1,做一个无限循环
try {
while (true) {
system.out.println("looping......");
thread.sleep(2000);
}
} catch (interruptedexception e) {
system.out.println("interrupted");
}
return "false";
} else {
// falg不为0或者1,则抛出异常
throw new exception("bad flag value!");
}
}
}
public static void main(string[] args) {
// 定义3个callable类型的任务
mycallableclass task1 = new mycallableclass(0);
mycallableclass task2 = new mycallableclass(1);
mycallableclass task3 = new mycallableclass(2);
// 创建一个执行任务的服务
executorservice es = executors.newfixedthreadpool(3);
try {
// 提交并执行任务,任务启动时返回了一个future对象,
// 如果想得到任务执行的结果或者是异常可对这个future对象进行操作
future future1 = es.submit(task1);
// 获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行
system.out.println("task1: " + future1.get());
future future2 = es.submit(task2);
// 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环
thread.sleep(5000);
system.out.println("task2 cancel: " + future2.cancel(true));
// 获取第三个任务的输出,因为执行第三个任务会引起异常
// 所以下面的语句将引起异常的抛出
future future3 = es.submit(task3);
system.out.println("task3: " + future3.get());
} catch (exception e) {
system.out.println(e.tostring());
}
// 停止任务执行服务
es.shutdownnow();
}
}
更多java多线程实现callable接口。