Java多線程處理List數據


多線程數量的問題,一般情況下,多線程數量要等於機器CPU核數-1.

實例1:

解決問題:如何讓n個線程順序遍歷含有n個元素的List集合

 

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 import org.apache.commons.lang3.ArrayUtils;
 4  
 5 public class Test_4 {
 6     /**
 7      * 多線程處理list
 8      *
 9      * @param data  數據list
10      * @param threadNum  線程數
11      */
12     public synchronized void handleList(List<String> data, int threadNum) {
13         int length = data.size();
14         int tl = length % threadNum == 0 ? length / threadNum : (length
15                 / threadNum + 1);
16  
17         for (int i = 0; i < threadNum; i++) {
18             int end = (i + 1) * tl;
19             HandleThread thread = new HandleThread("線程[" + (i + 1) + "] ",  data, i * tl, end > length ? length : end);
20             thread.start();
21         }
22     }
23  
24     class HandleThread extends Thread {
25         private String threadName;
26         private List<String> data;
27         private int start;
28         private int end;
29  
30         public HandleThread(String threadName, List<String> data, int start, int end) {
31             this.threadName = threadName;
32             this.data = data;
33             this.start = start;
34             this.end = end;
35         }
36         
37         public void run() {
38             List<String> subList = data.subList(start, end)/*.add("^&*")*/;
39             System.out.println(threadName+"處理了"+subList.size()+"條!");
40         }
41  
42     }
43  
44     public static void main(String[] args) {
45         Test_4 test = new Test_4();
46         // 准備數據
47         List<String> data = new ArrayList<String>();
48         for (int i = 0; i < 6666; i++) {
49             data.add("item" + i);
50         }
51         test.handleList(data, 5);
52         System.out.println(ArrayUtils.toString(data));
53     }
54 }
View Code

 

實例2:

List多線程並發讀取讀取現有的list對象

 1 //測試讀取List的線程類,大概34秒
 2 package com.thread.list;
 3  
 4 import java.util.ArrayList;
 5 import java.util.HashMap;
 6 import java.util.List;
 7 import java.util.Map;
 8  
 9 public class Main {
10     
11     public static void main(String[] args) {
12         
13         List<String> list = new ArrayList<String>();
14         Map<Long,Integer> map = new HashMap<Long,Integer>();
15 
16         for(int i = 0;i<1000;i++){
17             list.add(""+i);
18         }
19         
20         int pcount = Runtime.getRuntime().availableProcessors();        
21         long start = System.currentTimeMillis();        
22         
23         for(int i=0;i<pcount;i++){
24             
25            Thread t = new MyThread1(list,map);
26             map.put(t.getId(),Integer.valueOf(i));
27             t.start();
28             try {
29                 t.join();
30             } catch (InterruptedException e) {              
31                 e.printStackTrace();
32             }            
33            // System.out.println(list.get(i));
34         }        
35         System.out.println("----"+(System.currentTimeMillis() - start));
36     }    
37 }
38 
39 //線程類
40 package com.thread.list;
41  
42 import java.util.List;
43 import java.util.Map;
44  
45 public class MyThread1 extends Thread {
46  
47     private List<String> list;
48     private Map<Long,Integer> map;
49     
50     public MyThread1(List<String> list,Map<Long,Integer> map){
51         this.list = list;
52         this.map = map;
53     }
54     
55     @Override
56     public void run() {
57         
58         int pcount = Runtime.getRuntime().availableProcessors();
59         int i = map.get(Thread.currentThread().getId());
60         
61         for(;i<list.size();i+=pcount){
62             System.out.println(list.get(i));
63         }              
64     }    
65 }
View Code

實例3:

多線程分段處理List集合

場景:大數據List集合,需要對List集合中的數據同標准庫中數據進行對比,生成新增,更新,取消數據
解決方案:

  1. List集合分段,
  2. 動態創建線程池newFixedThreadPool
  3. 將對比操作在多線程中實現
 1 public static void main(String[] args) throws Exception {
 2 
 3         // 開始時間
 4         long start = System.currentTimeMillis();
 5         List<String> list = new ArrayList<String>();
 6 
 7         for (int i = 1; i <= 3000; i++) {
 8             list.add(i + "");
 9         }
10         // 每500條數據開啟一條線程
11         int threadSize = 500;
12         // 總數據條數
13         int dataSize = list.size();
14         // 線程數
15         int threadNum = dataSize / threadSize + 1;
16         // 定義標記,過濾threadNum為整數
17         boolean special = dataSize % threadSize == 0;
18 
19         // 創建一個線程池
20         ExecutorService exec = Executors.newFixedThreadPool(threadNum);
21         // 定義一個任務集合
22         List<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>();
23         Callable<Integer> task = null;
24         List<String> cutList = null;
25 
26         // 確定每條線程的數據
27         for (int i = 0; i < threadNum; i++) {
28             if (i == threadNum - 1) {
29                 if (special) {
30                     break;
31                 }
32                 cutList = list.subList(threadSize * i, dataSize);
33             } else {
34                 cutList = list.subList(threadSize * i, threadSize * (i + 1));
35             }
36             // System.out.println("第" + (i + 1) + "組:" + cutList.toString());
37             final List<String> listStr = cutList;
38             task = new Callable<Integer>() {
39 
40                 @Override
41                 public Integer call() throws Exception {
42                     System.out.println(Thread.currentThread().getName() + "線程:" + listStr);
43                     return 1;
44                 }
45             };
46             // 這里提交的任務容器列表和返回的Future列表存在順序對應的關系
47             tasks.add(task);
48         }
49 
50         List<Future<Integer>> results = exec.invokeAll(tasks);
51 
52         for (Future<Integer> future : results) {
53             System.out.println(future.get());
54         }
55 
56         // 關閉線程池
57         exec.shutdown();
58         System.out.println("線程任務執行結束");
59         System.err.println("執行任務消耗了 :" + (System.currentTimeMillis() - start) + "毫秒");
60     }
View Code


免責聲明!

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



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