java8新特性——並行流與串行流

並行流

就是把一個內容分成多個數據塊,並用不同的線程分別處理每個數據塊的流

java8中將並行進行了優化,我們可以很容易對數據進行並行操作

Stream API可以聲明性地通過parallel()與sequential()在並行流與順序流之間進行切換

在這裏插入圖片描述

Fork/Join框架與傳統線程池的區別

  • 採用“工作竊取”模式:
    • 當執行新的任務時它可以將其拆分分成更小的任務執行,並將小任務加到線程隊列中,然後再從一個隨機線程的隊列中偷一個並把它放在自己的隊列中
  • 相對於一般的線程池實現,fork/join框架的優勢體現在對其中包含的任務的處理方式上,在一般的線程池中,如果一個線程正在執行的任務由於某些原因無法繼續運行,那麼該線程會處於等待狀態。
  • 而fork/join框架視線中,如果某個子問題由於等待另外一個子問題的完成而無法繼續運行。那麼處理該子問題的線程會主動尋找其他尚未運行的子問題來執行。這種方式減少了線程的等待時間,提高了性能

原來使用fork-join:

  • 需要繼承RecursiveTask父類,重寫compute()方法,自己制定分配規則
public class ForkJoin extends RecursiveTask<Long> {

	//比如大數據熱搜,全局搜索熱搜詞,在數據量極高的情況下,使用forkjoin效率高

	private long start;
	private long end;

	private static final long ZERO_AREA = 10000; //臨界值

	public ForkJoin(long start, long end) {
		this.start = start;
		this.end = end;

	}

	/*
		把一個大數字拆分,拆一半,拆一半,直到拆到10000爲止,在10000範圍內累加
	 */

	@Override
	protected Long compute() {

		long length = end - start;

		if (length <= ZERO_AREA) {

			//到達臨界值就累加
			long sum = 0;
			for (long i = start; i < end; i++) {
				sum += i;
			}
			return sum;

		} else {
			//不達到臨界值,就要拆分
			long middle = (start + end) / 2;
			ForkJoin left = new ForkJoin(start,middle);
			left.fork();//拆分子任務,同時壓入線程隊列

			ForkJoin right =new  ForkJoin(middle+1,end);
			right.fork();

			return left.join() + right.join();

		}

	}

測試

public static void main(String[] args) {
		Instant start = Instant.now();

		ForkJoinPool pool = new ForkJoinPool();
		ForkJoinTask<Long> task = new ForkJoin(0,5000000000L); //0到五十個億的累加
		Long sum = pool.invoke(task);

		System.out.println("和爲 = " + sum);

		Instant end = Instant.now();
		System.out.println("耗時爲:"+Duration.between(start,end).toMillis() + "毫秒");
		//耗時爲:3946毫秒
}

java8的並行流

  • 底層還是forkjoin
  • 加個方法parallel()
/**
	 * java8並行流
	 */
	@Test
	public void test(){

		//累加,順序流
		OptionalLong aLong = LongStream.rangeClosed(0, 10000000L)
				.reduce(Long::sum);


        //累加,並行流,只要加個parallel()就行   底層還是forkjoin
		OptionalLong aLong2 = LongStream.rangeClosed(0, 10000000L)
				.parallel()
				.reduce(Long::sum);
		System.out.println("aLong2 = " + aLong2.getAsLong());

	}

運行的時候可以看一下cup的運行狀態,四核CPU全部拉滿,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章