定義一個測試類
public class TestParallelStream { private List<Integer> list; private int size; private CountDownLatch countDownLatch; @Before public void initList(){ list = new ArrayList<>(); size = 100; countDownLatch = new CountDownLatch(size); for(int i=0; i<size; i++) { list.add(i); } }
上面定義了一個100元素的list。
下面使用迭代器遍歷:
/** * 迭代器遍歷 * @throws Exception */ @Test public void testFor() throws Exception { long start = System.currentTimeMillis(); Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()){ System.out.print(iterator.next()); } System.out.println(); long end = System.currentTimeMillis(); System.out.println(end-start); }
結果耗時穩定一位數的毫秒
使用parallelStream的方式:
/**
* 使用parallelSteam.forEach()遍歷 * @throws Exception */ @Test public void testListForEach() throws Exception{ long start = System.currentTimeMillis(); list.parallelStream().forEach( l -> { System.out.print(l); countDownLatch.countDown(); } ); countDownLatch.await(); System.out.println(); long end = System.currentTimeMillis(); System.out.println(end-start); }
結果是穩定在50以上的兩位數的毫秒。
但是當我們要進行耗時的操作時,比如說IO,這里用Thread.sleep(100)模擬IO。
用迭代器處理模擬的IO的方式:
/** * 當有耗時操作時,使用迭代器遍歷 * @throws Exception */ @Test public void testForSleep() throws Exception { long start = System.currentTimeMillis(); Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()){ System.out.print(iterator.next()); Thread.sleep(100); } System.out.println(); long end = System.currentTimeMillis(); System.out.println(end-start); }
結果是比10000大一些的毫秒數。
用parallelStream處理模擬的IO:
/**
* 當有耗時操作時,使用parallelSteam.forEach()遍歷 * @throws Exception */ @Test public void testListParallelStream() throws Exception{ long start = System.currentTimeMillis(); list.parallelStream().forEach( l -> { System.out.print(l); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } countDownLatch.countDown(); } ); countDownLatch.await(); System.out.println(); long end = System.currentTimeMillis(); System.out.println(end-start); }
結果是比2500大一些的毫秒數。應該是跟我電腦4核有關,處理4個線程。是上面迭代器遍歷時間的1/4.
總結
當數據量不大或者沒有太耗時的操作時,順序執行(如iterator)往往比並行執行更快,畢竟,分配資源、准備線程池和其它相關資源也是需要時間的;
當任務涉及到耗時操作(如I/O)並且任務之間不互相依賴時,那么並行化就是一個不錯的選擇。通常而言,將這類程序並行化之后,執行速度會提升好幾個等級;
由於在並行環境中任務的執行順序是不確定的,因此對於依賴於順序的任務而言,並行化也許不能給出正確的結果。
參考: