java 多線程 Callable -- 分段處理一個大的list 然后再合並結果


本文代碼參考 http://bbs.csdn.net/topics/391070227?page=1   

下面是貼出的代碼:

public void dealListWithMutiThread(){
        List<Object> list = new ArrayList<Object>(10000);
        int index = 0;
        ExecutorService ex = Executors.newFixedThreadPool(5);
        int dealSize = 2000;
        List<Future<List<Object>>> futures = new ArrayList<>(5);
                //分配
        for(int i=0;i<= 5;i++,index+=dealSize){
            int start = index;
            if(start>=list.size()) break;
            int end = start + dealSize;
            end = end>list.size() ? list.size() : end;
            futures.add(ex.submit(new Task(list,start,end)));
        }
        try {
            //處理
            List<Object>  result = new ArrayList<>();
            for(Future<List<Object>> future : futures){
                //合並操作
                result.addAll(future.get());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
     
    private class Task implements Callable<List<Object>>{
         
        private List<Object> list;
        private int start;
        private int end;
         
        public Task(List<Object> list,int start,int end){
            this.list = list;
            this.start = start;
            this.end = end;
        }
 
        @Override
        public List<Object> call() throws Exception {
            Object obj = null;
            List<Object> retList = new ArrayList<Object>();
            for(int i=start;i<end;i++){
                obj = list.get(i);
                //你的處理邏輯
            }
            //返回處理結果
            return retList;
        }
    }

 注: 多線程操作一定比單線程快么?

  多線程編程的目的,就是"最大限度地利用CPU資源",當某一線程的處理不需要占用CPU而只和I/O,OEMBIOS等資源打交道時,讓需要占用CPU資源的其它線程有機會獲得CPU資源。 所以我開單線程時 cpu占用率可能不會達到100% ,但開多線程 cpu使用率 經常會達到100%;

多線程 和 多進程

如果采用多進程,那么就需要將線程所隸屬的該進程所需要的內存進行切換,這時間代價是很多的。而線程切換代價就很少,線程是可以共享內存的。所以采用多線程在切換上花費的比多進程少得多。
但是,線程切換還是需要時間消耗的,所以采用一個擁有兩個線程的進程執行所需要的時間比一個線程的進程執行兩次所需要的時間要多一些。即采用多線程不會提高程序的執行速度,反而會降低速度,但是對於用戶來說,可以減少用戶的響應時間。

綜上所述: 如果涉及到 IO等,不是一直占用cpu的操作時,多線程是可以提升效率的; 但是如果只是大量的計算,則多線程的效率會很明顯的不如單線程;

下面又粘入了一段 使用 ThreadLocal 的代碼 ;
來源:  http://blog.csdn.net/hardworking0323/article/details/52266325
/* 
 ThreadLocal 
 它就是一個容器,用於存放線程的局部變量,我認為應該叫做 ThreadLocalVariable(線程局部變量)才對, 
 真不理解為什么當初 Sun 公司的工程師這樣命名。 
 早在 JDK 1.2 的時代,java.lang.ThreadLocal 就誕生了, 
 它是為了解決多線程並發問題而設計的,只不過設計得有些難用,所以至今沒有得到廣泛使用 
 可以解決同步搶占資源的問題 
 ThreadLocal不是用來解決對象共享訪問問題的,而主要是提供了線程保持對象的方法和避免參數傳遞的方便的對象訪問方式  
 ThreadLocal的應用場合,最適合的是按線程多實例(每個線程對應一個實例)的對象的訪問,並且這個對象很多地方都要用到。  
 */  
public class DBUtil {  
    // 數據庫配置  
    private static final String driver = "com.mysql.jdbc.Driver";  
    private static final String url = "jdbc:mysql://localhost:3306/test";  
    private static final String username = "root";  
    private static final String password = "root";  
  
    // 定義一個用於放置數據庫連接的局部線程變量(使每個線程都擁有自己的連接)  
    private static ThreadLocal<Connection> connContainer = new ThreadLocal<Connection>();  
  
    // 獲取連接  
    public static Connection getConnection() {  
        Connection conn = connContainer.get();  
        try {  
            if (conn == ) {  
                Class.forName(driver);  
                conn = DriverManager.getConnection(url, username, password);  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            connContainer.set(conn);  
        }  
        return conn;  
    }  
  
    // 關閉連接  
    public static void closeConnection() {  
        Connection conn = connContainer.get();  
        try {  
            if (conn != ) {  
                conn.close();  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            connContainer.remove();  
        }  
    }  
}  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM