一,Fork/Join 框架
就是在必要的情況下,將一個大任務,進行拆分(fork)成若干個 小任務(拆到不可再拆時),再將一個個的小任務運算的結果進行 join 彙總.
實現原理圖:
1,Fork/Join 框架與傳統線程池的區別
採用 “工作竊取”模式(work-stealing): 當執行新的任務時它可以將其拆分分成更小的任務執行,並將小任務加到線 程隊列中,然後再從一個隨機線程的隊列中偷一個並把它放在自己的隊列中。 相對於一般的線程池實現,fork/join框架的優勢體現在對其中包含的任務的 處理方式上.在一般的線程池中,如果一個線程正在執行的任務由於某些原因 無法繼續運行,那麼該線程會處於等待狀態.而在fork/join框架實現中,如果 某個子問題由於等待另外一個子問題的完成而無法繼續運行.那麼處理該子 問題的線程會主動尋找其他尚未運行的子問題來執行.這種方式減少了線程 的等待時間,提高了性能.
2,並行流與串行流
並行流就是把一個內容分成多個數據塊,並用不同的線程分 別處理每個數據塊的流。
Java 8 中將並行進行了優化,我們可以很容易的對數據進行並 行操作。 Stream API 可以聲明性地通過 parallel() 與 sequential() 在並行流與順序流之間進行切換。
Fork/Join 框架代碼實現示例:
需求,給定開始值和結束值,進行累加計算
package com.atguigu.java8;
import java.util.concurrent.RecursiveTask;
public class ForkJoinCalculate extends RecursiveTask<Long>{
/**
*
*/
private static final long serialVersionUID = 13475679780L;
private long start;
private long end;
private static final long THRESHOLD = 10000L; //臨界值
public ForkJoinCalculate(long start, long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
long length = end - start;
if(length <= THRESHOLD){
long sum = 0;
for (long i = start; i <= end; i++) {
sum += i;
}
return sum;
}else{
long middle = (start + end) / 2;
ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
left.fork(); //拆分,並將該子任務壓入線程隊列
ForkJoinCalculate right = new ForkJoinCalculate(middle+1, end);
right.fork();
return left.join() + right.join();
}
}
}
package com.atguigu.java8;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
import org.junit.Test;
public class TestForkJoin {
@Test
public void test1(){
long start = System.currentTimeMillis();
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinCalculate(0L, 10000000000L);
long sum = pool.invoke(task);
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println("耗費的時間爲: " + (end - start)); //112-1953-1988-2654-2647-20663-113808
}
@Test
public void test2(){
long start = System.currentTimeMillis();
long sum = 0L;
for (long i = 0L; i <= 10000000000L; i++) {
sum += i;
}
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println("耗費的時間爲: " + (end - start)); //34-3174-3132-4227-4223-31583
}
@Test
public void test3(){
long start = System.currentTimeMillis();
Long sum = LongStream.rangeClosed(0L, 10000000000L)
.parallel()
.sum();
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println("耗費的時間爲: " + (end - start)); //2061-2053-2086-18926
}
}
二,Optional 類
Optional<T> 類(java.util.Optional) 是一個容器類,代表一個值存在或不存在, 原來用 null 表示一個值不存在,現在 Optional 可以更好的表達這個概念。並且 可以避免空指針異常。
常用方法:
Optional.of(T t) : 創建一個 Optional 實例
Optional.empty() : 創建一個空的 Optional 實例
Optional.ofNullable(T t):若 t 不爲 null,創建 Optional 實例,否則創建空實例
isPresent() : 判斷是否包含值
orElse(T t) : 如果調用對象包含值,返回該值,否則返回t
orElseGet(Supplier s) :如果調用對象包含值,返回該值,否則返回 s 獲取的值
map(Function f): 如果有值對其處理,並返回處理後的Optional,否則返回 Optional.empty()
flatMap(Function mapper):與 map 類似,要求返回值必須是Optional
方法使用代碼示例:
package com.atguigu.java8;
import java.util.Optional;
import org.junit.Test;
/*
* 一、Optional 容器類:用於儘量避免空指針異常
* Optional.of(T t) : 創建一個 Optional 實例
* Optional.empty() : 創建一個空的 Optional 實例
* Optional.ofNullable(T t):若 t 不爲 null,創建 Optional 實例,否則創建空實例
* isPresent() : 判斷是否包含值
* orElse(T t) : 如果調用對象包含值,返回該值,否則返回t
* orElseGet(Supplier s) :如果調用對象包含值,返回該值,否則返回 s 獲取的值
* map(Function f): 如果有值對其處理,並返回處理後的Optional,否則返回 Optional.empty()
* flatMap(Function mapper):與 map 類似,要求返回值必須是Optional
*/
public class TestOptional {
@Test
public void test4(){
Optional<Employee> op = Optional.of(new Employee(101, "張三", 18, 9999.99));
Optional<String> op2 = op.map(Employee::getName);
System.out.println(op2.get());
Optional<String> op3 = op.flatMap((e) -> Optional.of(e.getName()));
System.out.println(op3.get());
}
@Test
public void test3(){
Optional<Employee> op = Optional.ofNullable(new Employee());
if(op.isPresent()){
System.out.println(op.get());
}
Employee emp = op.orElse(new Employee("張三"));
System.out.println(emp);
Employee emp2 = op.orElseGet(() -> new Employee());
System.out.println(emp2);
}
@Test
public void test2(){
/*Optional<Employee> op = Optional.ofNullable(null);
System.out.println(op.get());*/
// Optional<Employee> op = Optional.empty();
// System.out.println(op.get());
}
@Test
public void test1(){
Optional<Employee> op = Optional.of(new Employee());
Employee emp = op.get();
System.out.println(emp);
}
@Test
public void test5(){
Man man = new Man();
String name = getGodnessName(man);
System.out.println(name);
}
//需求:獲取一個男人心中女神的名字
public String getGodnessName(Man man){
if(man != null){
Godness g = man.getGod();
if(g != null){
return g.getName();
}
}
return "蒼老師";
}
//運用 Optional 的實體類
@Test
public void test6(){
Optional<Godness> godness = Optional.ofNullable(new Godness("林志玲"));
Optional<NewMan> op = Optional.ofNullable(new NewMan(godness));
String name = getGodnessName2(op);
System.out.println(name);
}
public String getGodnessName2(Optional<NewMan> man){
return man.orElse(new NewMan())
.getGodness()
.orElse(new Godness("蒼老師"))
.getName();
}
}