并行流與串行流
并行流就是把一個(gè)內(nèi)容分成多個(gè)數(shù)據(jù)塊,并用不同的線程分別處理每個(gè)數(shù)據(jù)塊的流。
java 8 中將并行進(jìn)行了優(yōu)化,我們可以很容易的對(duì)數(shù)據(jù)進(jìn)行并行操作。stream api 可以聲明性地通過(guò) parallel()與 sequential()在并行流與順序流之間進(jìn)行切換。
了解 fork/join 框架
fork/join 框架:就是在必要的情況下,將一個(gè)大任務(wù),進(jìn)形拆分(fork)成若干個(gè)小任務(wù)(拆到不可再拆時(shí)),再將一個(gè)個(gè)的小任務(wù)運(yùn)行的結(jié)果進(jìn)行join匯總。
fork/join 框架與傳統(tǒng)線程池的區(qū)別:
采用“工作竊取”模式(work-stealing):
當(dāng)執(zhí)行新的任務(wù)時(shí),它可以將其拆分成更小的任務(wù)執(zhí)行,并將小任務(wù)加到線程隊(duì)列中,然后再?gòu)囊粋€(gè)隨機(jī)線程的隊(duì)列中偷一個(gè)并把它放在自己的隊(duì)列中。
相對(duì)于一般的線程池實(shí)現(xiàn),fork/join框架的優(yōu)勢(shì)體現(xiàn)在對(duì)其中包含的任務(wù)的處理方式上.在一般的線程池中,如果一個(gè)線程正在執(zhí)行的任務(wù)由于某些原因無(wú)法繼續(xù)運(yùn)行,那么該線程會(huì)處于等待狀態(tài).而在fork/join框架實(shí)現(xiàn)中,如果某個(gè)子問(wèn)題由于等待另外一個(gè)子問(wèn)題的完成而無(wú)法繼續(xù)運(yùn)行.那么處理該子問(wèn)題的線程會(huì)主動(dòng)尋找其他尚未運(yùn)行的子問(wèn)題來(lái)執(zhí)行.這種方式減少了線程的等待時(shí)間,提高了性能。
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( "消耗時(shí)間" +duration.between(start, end).tomillis()+ "ms" ); //消耗時(shí)間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( "消耗時(shí)間" + duration.between(start, end).tomillis()+ "ms" ); //消耗時(shí)間2418ms } } class forkjoincalculate extends recursivetask< long >{ private static final long serialversionuid = 1234567890l; //序列號(hào) 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) 是一個(gè)容器類,代表一個(gè)值存在或不存在。
原來(lái)用null表示一個(gè)值不存在,現(xiàn)在 optional可以更好的表達(dá)這個(gè)概念。并且可以避免空指針異常。
常用方法:
optional.of(t t) : 創(chuàng)建一個(gè) optional 實(shí)例
optional.empty() : 創(chuàng)建一個(gè)空的 optional 實(shí)例
optional.ofnullable(t t):若 t 不為 null,創(chuàng)建 optional 實(shí)例,否則創(chuàng)建空實(shí)例
ispresent() : 判斷是否包含值
orelse(t t) : 如果調(diào)用對(duì)象包含值,返回該值,否則返回t
orelseget(supplier s) :如果調(diào)用對(duì)象包含值,返回該值,否則返回 s 獲取的值
map(function f): 如果有值對(duì)其處理,并返回處理后的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); } //需求:獲取一個(gè)男人心中女神的名字 public string getgodnessname(man man){ if (man!= null ){ godness g=man.getgod(); if (g!= null ){ return g.getname(); } } return "蒼老師" ; } //運(yùn)用optional的實(shí)體類 @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框架使用心得的全部?jī)?nèi)容,大家在學(xué)習(xí)的時(shí)候如果還有任何不明白的地方可以在下方的留言區(qū)討論。
原文鏈接:https://my.oschina.net/u/3746673/blog/1594197