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