多執行緒之Future和Callable【高效能應用場景java.util.concurrent】
業務場景:
如查一個數據集合,第一頁至第一百頁,返回總頁數的總結集,然後匯出。
一次需要limit 0 10000,這樣,一個SQL查詢出非常慢。
但用100個執行緒,一個執行緒只查limit0 10 就非常快了,
利用多執行緒的特性,返回多個集合,在順序合併成總集合。
下面是concurrent.Future 例子
concurrent.Callable
package com.test.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * Future<List<User>> * * 應用場景 :1.多執行緒,每個執行緒平均任務耗時一樣 * 2.需要順序返回的 * * 順序返回,如多個分頁,但第一頁需要先返回 * * @author 汪興安 * */ public class ThreadTest { /** * 定義執行緒池 */ public static ExecutorService executos = Executors.newFixedThreadPool(5); public static void main(String[] args) { /** * 定義集合裝結果集 */ List<User> totalList = new ArrayList<User>(); /** * 定義 Future泛型的集合物件,裝多執行緒的,返回資訊 */ List<Future<List<User>>> list = new ArrayList<Future<List<User>>>(); try { int pageIndex = 0; int maxPage = 6; for (pageIndex = 0; pageIndex < maxPage; pageIndex++) { /** * executos.submit 返回執行緒未來結果 */ Future<List<User>> future = executos.submit(new DemoThread(pageIndex)); list.add(future); } for (Future<List<User>> dataFuture : list) { //// 獲得第一個任務的結果,如果呼叫get方法,當前執行緒會等待任務執行完畢後才往下執行 totalList.addAll(dataFuture.get()); //dataFuture.get() 這裡會阻塞 有順序的哦 } //得到分頁後結果總共集合 for (int i = 0; i < totalList.size(); i++) { System.out.println(totalList.get(i).getName()); } } catch (Exception e) { e.printStackTrace(); } executos.shutdownNow(); } /** * 查詢第1頁 查詢第3頁 查詢第5頁 查詢第2頁 查詢第4頁 查詢第0頁 -----結果會順序返回,不用你操心順序問題啦 anan0 anan1 anan2 anan3 anan4 anan5 */ }
package com.test.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; /** * Callable 支援有返回值的多執行緒 * @author 汪興安 * */ public class DemoThread implements Callable<List<User>> { private int pageIndex; /** * 通過構造器,初始化 * @param pageIndex */ public DemoThread(int pageIndex) { this.pageIndex = pageIndex; } @Override public List<User> call() throws Exception { //模擬每個執行緒執行耗時不一樣 if(pageIndex%2==0) { Thread.sleep(5000); }else { Thread.sleep(2000); } System.out.println("查詢第" + pageIndex + "頁"); List<User> list = new ArrayList<User>(); /** * 模擬查詢的資料物件 */ User user=new User(); user.setAge(""+pageIndex); user.setName("anan"+pageIndex); list.add(user); return list; } }
===================================華麗分割線=================================================================================
package com.test.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutionException; /** * * @author 汪興安 * 應用場景 :1.每個執行緒耗時差別大,誰先完成,誰返回 * 對順序沒有要求。 * * * * CompletionService 的效能更高。 * 考慮如下場景:多執行緒下載,結果用Future返回。 * 第一個檔案特別大,後面的檔案很小。 * 用方法1,能很快知道已經下載完檔案的結果(不是第一個); * */ public class CallableAndFuture { public static void main(String[] args) { List<User> totalList = new ArrayList<User>(); ExecutorService threadPool = Executors.newCachedThreadPool(); CompletionService<List<User>> cs = new ExecutorCompletionService<List<User>>(threadPool); for(int i = 0; i < 6; i++) { cs.submit(new DemoThread(i)); } // 可能做一些事情 for(int i = 0; i < 6; i++) { try { totalList.addAll(cs.take().get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } //得到分頁後結果總共集合 for (int i = 0; i < totalList.size(); i++) { System.out.println(totalList.get(i).getName()); } } /** * 查詢第3頁 查詢第1頁 查詢第5頁 查詢第2頁 查詢第0頁 查詢第4頁 anan5 anan1 anan3 anan2 anan0 anan4 */ }
總結:兩種方式,應用場景不一樣
Future<List<User>> future = executos.submit(new DemoThread(pageIndex)); 這種可以保證返回的順序
CompletionService<List<User>> cs = new ExecutorCompletionService<List<User>>(threadPool);,返回不保證順序,誰先執行完,誰先返回。
效率上CompletionService更高,實際專案需要根據具體業務需求選擇。
相關推薦
多執行緒之Future和Callable【高效能應用場景java.util.concurrent】
業務場景: 如查一個數據集合,第一頁至第一百頁,返回總頁數的總結集,然後匯出。 一次需要limit 0 10000,這樣,一個SQL查詢出非常慢。 但用100個執行緒,一個執行緒只查limit0 10 就非常快了, 利用多執行緒的特性,返回多個集合,在順序合併成總集合。
java 多執行緒之future用法和意義
在併發程式設計時,一般使用runnable,然後扔給執行緒池完事,這種情況下不需要執行緒的結果。所以run的返回值是void型別。 如果是一個多執行緒協作程式,比如菲波拉切數列,1,1,2,3,5,8...使用多執行緒來計算。但後者需要前者的結果,就需要用callable介
從零開始學多執行緒之取消和關閉(六)
小節 為什麼需要取消和關閉: 有時候我們希望在任務或執行緒自然結束之前就停止它們,可能因為使用者取消了操作,或者應用程式需要快速關閉. 取消和關閉的好處: 不會浪費資源執行一些沒用的操作、保證程式的正常退出. Java沒有提供任何機制,來安全地強迫執行緒停止手頭的工作.它提供中斷(執行緒
IOS多執行緒之NSoperation和GCD的比較
GCD是基於c的底層api,NSOperation屬於object-c類。iOS首先引入的是NSOperation,IOS4之後引入了GCD和NSOperationQueue並且其內部是用gcd實現的。 相對於GCD: 1,NSOperation擁有更多的函式可用,具體檢視api。
多執行緒之Future使用詳解
什麼是Future Future是一個未來物件,裡面儲存這執行緒處理結果,它像一個提貨憑證,拿著它你可以隨時去提取結果 什麼時候使用 在兩種情況下,離開Future幾乎很難辦。 一種情況是拆分訂單,比如你的應用收到一個批量訂單,此時如果要求最快的處理訂單,那麼需要併發
多執行緒之CountDownLatch和CyclicBarrier的區別和用法
一.CountDownLatch的使用 CountDownLatch經常用於監聽某些初始化操作,等初始化執行完畢後,再通知主執行緒繼續工作。 CountDownLatch定義: 一個同步輔助類,在完成一組正在其他執行緒中執行的操作之前,它允許一個或多個執行緒一直等待。用給定的計數 初
Java多執行緒之interrupt()和執行緒終止方式
1. interrupt()說明 在介紹終止執行緒的方式之前,有必要先對interrupt()進行了解。 關於interrupt(),java的djk文件描述如下:http://docs.oracle.com/javase/7/docs/api/ Interrupts this thread
java多執行緒之ReentrantLock和 Condition
ReentrantLock 是JDK中內建鎖,也稱可重入鎖,API也較為簡單。 Condition 可實現 執行緒間通訊,由ReentrantLock 例項產生即 lock.new Condition(); 下面這個demo模擬最簡單的生產者 消費者模式,Add執行緒模
多執行緒之start和run
1) start: 用start方法來啟動執行緒,真正實現了多執行緒執行,這時無需等待run方法體程式碼執行完畢而直接繼續執行下面的程式碼。通過呼叫Thread類的start()方法來啟動一個執行緒,這時此執行緒處於就緒(可執行)狀態,並沒有執行,一旦得到c
JAVA多執行緒之Runnable和Thread比較
在我們開發的過程中常常會碰到多執行緒的問題,對於多執行緒的實現方式主要有兩種:實現Runnable介面、繼承Thread類。對於這兩種多執行緒的實現方式也是有著一些差異。既然實現了多執行緒那必然離不開管理這些執行緒,當問題比簡單時一個或者幾個執行緒就OK了,也涉
java多執行緒之Future模式使用
Future模式簡述 傳統單執行緒環境下,呼叫函式是同步的,必須等待程式返回結果後,才可進行其他處理。 Futrue模式下,呼叫方式改為非同步。 Futrue模式的核心在於:充分利用主函式中的等待
Java多執行緒之 Thread VS Runnable 【帶案例】
為此,我們舉個例子,假設有火車站有三個視窗,在賣火車票,總共只有5張票。每一個執行緒相當於一個視窗,分別售票 <strong>package com.thread; class my
java多執行緒之synchronized和volatile關鍵字
synchronized同步方法 髒讀 在多個執行緒對同一個物件中的例項變數進行併發訪問的時候,取到的資料可能是被更改過的,稱之為“髒讀”,這就是非執行緒安全的。解決的方法為synchronized關鍵字進行同步,使之操作變成同步而非非同步。 public
JAVA多執行緒之Future模式
Future模式有點類似於商品訂單。比如在網購時,當看中某一個商品時,就可以提交訂單,當訂單處理完成後,在家裡等待商品送貨上門即可。或者說更形象的我們傳送Ajax請求的時候,頁面是非同步的進行後臺處理,使用者無需一直等待請求的結果,可繼續瀏覽或操作其他內容。下面看一個例子:1
Java多執行緒之Callable和Future介面的實現
Callable和Future Callable介面定義了一個call方法可以作為執行緒的執行體,但call方法比run方法更強大: A、call方法可以有返回值 B、call方法可以申明丟擲異常 Callable介面是JDK5後
Java多執行緒之Executor框架<Callable、Future、Executor和ExecutorService>
引言 Executor框架是指JDK 1.5中引入的一系列併發庫中與Executor相關的功能類,包括Executor、Exec
【Qt多執行緒之執行緒的等待和喚醒】QWaitCondition
QWatiCondition的成員函式 ·QWaitCondition() ·~QWaitCondition() ·bool wait ( QMutex * mutex, unsigned long time = ULONG_MAX ) ·vo
多執行緒之futureTask(future,callable)例項,jdbc資料多執行緒查詢
最近遇到一個這樣的功能要求。在查詢資料時,由於查詢的資料量比較大,一次查詢(一條SQL語句中包含太多的條件)查詢起來很慢,大約要10S左右才能查詢出來,這樣體驗太不好了,需要進行優化。今天想了想,打算採用在後端把一條SQL進行拆分,拆分成為多條SQL語句,再拋給多個執行緒去
Java多執行緒(二)——Callable、Future和FutureTask
在上一章節我們介紹了Java實現多執行緒最常用的兩種方式,但是那兩種方式實現執行緒的時候並不能返回執行緒的執行結果。然而有些場景我們需要得到執行緒的執行結果,比如要計算每個部門的這個月的工資,然後進行總計(假設有n個部門,計算每個部門的工資需要花費m個小時,計算
多執行緒之IO密集型和CPU密集型
CPU密集型(CPU-bound) CPU密集型也叫計算密集型,指的是系統的硬碟、記憶體效能相對CPU要好很多,此時,系統運作大部分的狀況是CPU Loading 100%,CPU要讀/寫I/O(硬碟/記憶體),I/O在很短的時間就可以完成,而CPU還有許多運算要處理,CPU Loading很高