本人開發的開發者技術變現資源彙集地,你們支持下,下面是網址java
https://www.baiydu.comandroid
1、主要使用類數據庫
1. ExecutorServicejson
java線程池類網頁爬蟲
申明方式:ExecutorService exc = Executors.newFixedThreadPool(requestParameterArray.length()); api
參數:requestParameterArray.length()是請求線程的總數量,其中每個成員存放單個線程所需參數。緩存
代碼:網絡
2.Future多線程
Future是一個接口,他提供給了咱們方法來檢測當前的任務是否已經結束,還能夠等待任務結束而且拿到一個結果,經過調用Future的get()方法能夠當任務結束後返回一個結果值,若是線程裏的任何一個線程工做沒有結束,則線程會自動阻塞,直到任務執行完畢,咱們能夠經過調用cancel()方法來中止一個任務,若是任務已經中止,則cancel()方法會返回true;若是任務已經完成或者已經中止了或者這個任務沒法中止,則cancel()會返回一個false。當一個任務被成功中止後,他沒法再次執行。isDone()和isCancel()方法能夠判斷當前工做是否完成和是否取消,他的做用經過callable的回調得到咱們請求的結果。ide
ExecutorService/Future的執行代碼類
public class AAAThreadHttpRequest { //首頁返回所需的參數和接口,電影接口 //熱門電影 private String hotfilmUrl = "http://expand.video.iqiyi.com/api/top/list.json?apiKey=?&topType=1&categoryId=1&limit=30&sr=1"; //熱門電視劇 private String hotdianshijuUrl = "http://expand.video.iqiyi.com/api/top/list.json?apiKey=?&topType=1&categoryId=2&limit=5&sr=2"; //熱門動漫 private String hotanimationUrl = "http://expand.video.iqiyi.com/api/top/list.json?apiKey=?&topType=1&categoryId=4&limit=5&sr=3"; //第一個分段數據 private String segmentOneUrl ="http://expand.video.iqiyi.com/api/top/list.json?apiKey=?&topType=1&categoryId=7&limit=6&sr=5"; //淘寶客 public LinkedList<JSONObject> ShiPinThreadHandle() throws JSONException, IOException, InterruptedException, ExecutionException { //組合線程請求參數 JSONArray requestParameterArray=new JSONArray(); JSONObject a=new JSONObject(); a.put("requestUrl", hotfilmUrl); a.put("dataType", "hotFilm"); a.put("type", "shipin"); JSONObject a1=new JSONObject(); a1.put("requestUrl", hotdianshijuUrl); a1.put("dataType", "hotDianshiju"); a1.put("type", "shipin"); JSONObject a2=new JSONObject(); a2.put("requestUrl", hotanimationUrl); a2.put("dataType", "hotDongman"); a2.put("type", "shipin"); JSONObject a3=new JSONObject(); a3.put("requestUrl", segmentOneUrl); a3.put("dataType", "firstSegmentData"); a3.put("type", "shipin"); requestParameterArray.put(a); requestParameterArray.put(a1); requestParameterArray.put(a2); requestParameterArray.put(a3); //申明線程池 ExecutorService exc = Executors.newFixedThreadPool(requestParameterArray.length()); //申明數據回調處理類List<Future<JSONObject>> List<Future<JSONObject>> futures = new ArrayList<Future< JSONObject>>(); for (int i =0; i < requestParameterArray.length(); i++) { JSONObject singleobje=requestParameterArray.getJSONObject(i); //申請單個線程執行類 ShiPinThreadHandleRequest call =new ShiPinThreadHandleRequest(singleobje); //提交單個線程 Future< JSONObject> future = exc.submit(call); //將每一個線程放入線程集合, 這裏若是任何一個線程的執行結果沒有回調,線程都會自動堵塞 futures.add(future); } //全部線程執行完畢以後會執行下面的循環,而後經過循環每一個個線程後執行線程的get()方法每一個線程執行的結果 for (Future< JSONObject> future : futures) { JSONObject json= future.get(); AAAANewAppShareSingleton.getInstance().homePageSessionDictionary.put(json.getString("dataType"), json.getJSONArray("returnData")); } AAAANewAppShareSingleton.getInstance().homeIsOrNoReturn=1; //關閉線程池 exc.shutdown(); //這裏因爲我直接將返回結果放入到單利中緩存了,全部返回null return null; }
3.Callable
線程執行者,咱們的數據將在這個類的構造函數裏面執行,這個類自帶了回調函數。當執行結果返回時會經過它自帶的回調將請求結果反饋給Future。
Callable執行代碼類
public class ShiPinThreadHandleRequest implements Callable<JSONObject> { private JSONObject parameter; public ShiPinThreadHandleRequest(JSONObject parameter) throws JSONException, IOException { this.parameter=parameter; try { String HtmlJson=httpGetRequest(this.parameter.getString("requestUrl")); JSONObject object=new JSONObject(HtmlJson); //請求的愛奇藝接口 if(this.parameter.get("type").equals("shipin")) { JSONArray returnArray=object.getJSONArray("data"); if(this.parameter.getString("dataType").equals("firstSegmentData")) { JSONArray againArray=new JSONArray(); for (int j=0;j<returnArray.length();j++) { JSONArray tempArrray=new JSONArray(); tempArrray.put(returnArray.getJSONObject(j)); tempArrray.put(returnArray.getJSONObject(j+1)); againArray.put(tempArrray); j=j+1; } this.parameter.put("returnData",againArray); } else { this.parameter.put("returnData",returnArray); } } //請求的淘寶客接口 else { } } catch(Exception e) { } } //數據回調 public JSONObject call() throws Exception { return this.parameter; } }
4.http請求方法
public String httpGetRequest(String urlString1) { String result = ""; BufferedReader in = null; try { URL realUrl = new URL(urlString1); // 打開和URL之間的鏈接 URLConnection connection = realUrl.openConnection(); // 設置通用的請求屬性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 創建實際的鏈接 connection.connect(); // 獲取全部響應頭字段 Map<String, List<String>> map = connection.getHeaderFields(); // 遍歷全部的響應頭字段 for (String key : map.keySet()) { } // 定義 BufferedReader輸入流來讀取URL的響應 in = new BufferedReader(new InputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("發送GET請求出現異常!" + e); e.printStackTrace(); } // 使用finally塊來關閉輸入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; }
2、適合的使用場景
複雜的網頁爬蟲,如要同時請求多個不一樣網頁的數據,而且須要執行不一樣的數據處理,這個是很是合適的,執行線程傳遞的參數到最後callback是會附帶一塊兒反饋,你能夠根據請求時的附帶的類型參數進行判斷。 複雜的首頁數據,同時須要請求不一樣數據庫的不一樣接口。
3、優點
解決了多線程中複雜的線程堵塞問題,由於有future,它已經給你作了全部的事。
本人創業作的一款androidApp, 下載量已經有2000多萬,各類當前熱門的網絡手機獎勵紅包所有集成,另外還有熱門電影和淘寶高額優惠券!很適合各種型的用戶。