調用方法:
/** * 點擊量/月(年)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();}}以上就是本文的全部內容了,有需要的小伙伴可以參考下