并行流與串行流
并行流就是把一個內容分成多個數據塊,并用不同的線程分別處理每個數據塊的流。
java 8 中將并行進行了優化,我們可以很容易的對數據進行并行操作。stream api 可以聲明性地通過 parallel()與 sequential()在并行流與順序流之間進行切換。
了解 fork/join 框架
fork/join 框架:就是在必要的情況下,將一個大任務,進形拆分(fork)成若干個小任務(拆到不可再拆時),再將一個個的小任務運行的結果進行join匯總。
fork/join 框架與傳統線程池的區別:
采用“工作竊取”模式(work-stealing):
當執行新的任務時,它可以將其拆分成更小的任務執行,并將小任務加到線程隊列中,然后再從一個隨機線程的隊列中偷一個并把它放在自己的隊列中。
相對于一般的線程池實現,fork/join框架的優勢體現在對其中包含的任務的處理方式上.在一般的線程池中,如果一個線程正在執行的任務由于某些原因無法繼續運行,那么該線程會處于等待狀態.而在fork/join框架實現中,如果某個子問題由于等待另外一個子問題的完成而無法繼續運行.那么處理該子問題的線程會主動尋找其他尚未運行的子問題來執行.這種方式減少了線程的等待時間,提高了性能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
import java.time.duration; import java.time.instant; import java.util.concurrent.forkjoinpool; import java.util.concurrent.forkjointask; import java.util.concurrent.recursivetask; import java.util.stream.longstream; public class testforkjoin { public static void main(string[] xx){ } private static void test1(){ instant start=instant.now(); forkjoinpool pool= new forkjoinpool(); forkjointask< long > task = new forkjoincalculate(0l, 10000000000l); long sum = pool.invoke(task); system.out.println(sum); instant end=instant.now(); system.out.println( "消耗時間" +duration.between(start, end).tomillis()+ "ms" ); //消耗時間3409ms } private static void test2(){ instant start=instant.now(); long sum = longstream.rangeclosed(0l, 10000l) .parallel() .reduce( 0 , long ::sum); system.out.println(sum); instant end=instant.now(); system.out.println( "消耗時間" + duration.between(start, end).tomillis()+ "ms" ); //消耗時間2418ms } } class forkjoincalculate extends recursivetask< long >{ private static final long serialversionuid = 1234567890l; //序列號 private long start; private long end; private static final long threshold=2500000000l; //臨界值 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(); } } } |
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class optionaltest1 { public static void main(string[] args){ string s = new string( "ha" ); // optional<string> op = optional.of(null); // // string s1 = op.get(); // system.out.println(s1); // optional<string> op1 = optional.empty(); // string s1 = op1.get(); // system.out.println(s1); optional<string> op1 = optional.ofnullable( null ); // system.out.println(op1.ispresent()); // system.out.println(op1.orelse(new string("google"))); //system.out.println(op1.orelseget(() -> new string("ali"))); optional<string> op2 = op1.map((x) -> x.tolowercase()); string s2 = op2.get(); system.out.println(s2); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
@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(); } //注意:optional 不能被序列化 public class newman { private optional<godness> godness = optional.empty(); private godness god; public optional<godness> getgod(){ return optional.of(god); } public newman() { } public newman(optional<godness> godness) { this .godness = godness; } public optional<godness> getgodness() { return godness; } public void setgodness(optional<godness> godness) { this .godness = godness; } @override public string tostring() { return "newman [godness=" + godness + "]" ; } } |
以上就是我們給大家整理的java8中forkjoin和optional框架使用心得的全部內容,大家在學習的時候如果還有任何不明白的地方可以在下方的留言區討論。
原文鏈接:https://my.oschina.net/u/3746673/blog/1594197