JUC四大并发类的简单介绍

有人在群里问JUC的四大并发类该怎么用?记不住怎么办?于是乎本着复习加导学的目的写了简单的用例,在此记录一下

CountDownLatch

CountDownLatch一般用于主线程等待所有子线程执行完毕的场景,比如:老师要等所有的小朋友集合了才带他们回教室。

下面是个例子:

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80

package Concurrent



import java.util.concurrent.CountDownLatch

import java.util.concurrent.LinkedBlockingDeque

import java.util.concurrent.ThreadPoolExecutor

import java.util.concurrent.TimeUnit



/**

* describe: CountDownLatch 示例

* author: kaithmy

* date: 2018/8/10 17:03

**/

fun main(args: Array<String>) {

val threadPoolExecutor = ThreadPoolExecutor(10, 20, 10,

TimeUnit.SECONDS, LinkedBlockingDeque())



//队伍总共5个位置

val countDownLatch = CountDownLatch(5)



println("老师: ${Thread.currentThread().name} 孩子们,该集合啦! ")



//总共5个小朋友

for (i in 1..5) {

threadPoolExecutor.execute {

println("小朋友: ${Thread.currentThread().name} 我来啦!奔跑ing")

Thread.sleep((i * 1000).toLong())

println("小朋友: ${Thread.currentThread().name} 到位!yeah! ")



//占用一个队伍位置

countDownLatch.countDown()

}

}



//等待队伍位置被占满

countDownLatch.await()



//队伍位置满了就回教室啦

println("老师: ${Thread.currentThread().name} 既然都到了,那我们回教室吧! ")



}

执行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

老师: main 孩子们,该集合啦!

小朋友: pool-1-thread-1 我来啦!奔跑ing

小朋友: pool-1-thread-2 我来啦!奔跑ing

小朋友: pool-1-thread-3 我来啦!奔跑ing

小朋友: pool-1-thread-4 我来啦!奔跑ing

小朋友: pool-1-thread-5 我来啦!奔跑ing

小朋友: pool-1-thread-1 到位!yeah!

小朋友: pool-1-thread-2 到位!yeah!

小朋友: pool-1-thread-3 到位!yeah!

小朋友: pool-1-thread-4 到位!yeah!

小朋友: pool-1-thread-5 到位!yeah!

老师: main 既然都到了,那我们回教室吧!

CyclicBarrier

CyclicBarrier一般用于子线程间等待,就绪后再同时执行,具体执行顺序由CPU进行调度,比如:老师举行一次吃零食大赛,要等5位选手到齐了才能开始比赛。

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

package Concurrent



import java.util.concurrent.*



/**

* describe: CyclicBarrier 示例

* author: kaithmy

* date: 2018/8/7 14:59

**/

fun main(args: Array<String>) {

val threadPoolExecutor = ThreadPoolExecutor(10, 20, 10,

TimeUnit.SECONDS, LinkedBlockingDeque())



//总共5个比赛名额

val cyclicBarrier = CyclicBarrier(5, Runnable {

println("老师: 人到齐了,比赛开始!")

})



//总共5个小朋友参赛

for (i in 1..5) {

threadPoolExecutor.execute {

println("小朋友$i:我准备好啦!")

//等待其他小朋友到场

cyclicBarrier.await()



println("小朋友$i:我开始吃了!")

//模拟吃饭时长

Thread.sleep((i * 1000).toLong())

println("小朋友$i:我吃完了!")

}

}

}

执行结果如下:

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

小朋友2:我准备好啦!

小朋友3:我准备好啦!

小朋友1:我准备好啦!

小朋友4:我准备好啦!

小朋友5:我准备好啦!

老师: 人到齐了,比赛开始!

小朋友5:我开始吃了!

小朋友2:我开始吃了!

小朋友1:我开始吃了!

小朋友3:我开始吃了!

小朋友4:我开始吃了!

小朋友1:我吃完了!

小朋友2:我吃完了!

小朋友3:我吃完了!

小朋友4:我吃完了!

小朋友5:我吃完了!

Future

Future适用于需要即时获取子线程的执行结果的情况,可在获取结果时设置超时时间控制获取结果的时机,以免阻塞。

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

package Concurrent



import java.util.concurrent.Callable

import java.util.concurrent.LinkedBlockingDeque

import java.util.concurrent.ThreadPoolExecutor

import java.util.concurrent.TimeUnit



/**

* describe: Future 示例

* author: kaithmy

* date: 2018/8/10 15:35

**/

fun main(args: Array<String>) {

val threadPoolExecutor = ThreadPoolExecutor(10, 20, 10,

TimeUnit.SECONDS, LinkedBlockingDeque())



for (i in 1..5) {

//提交callable并获取future对象

val future = threadPoolExecutor.submit(MyFutureTask(i.toString(), i))



try {

//通过future获取执行结果,并设置超时时间为2s

val result = future.get(2, TimeUnit.SECONDS)

println("Thread $i :拿到结果啦!是 $result 哦")

} catch (e: Exception) {

println("Thread $i :超时了呢,$e ")

//超时取消

future.cancel(true)

}



}



}



class MyFutureTask(var name: String, var second: Int) : Callable<Int> {

override fun call(): Int {

println("子线程:$name 开始")



//模拟耗时操作

Thread.sleep((second * 1000).toLong())



println("子线程:$name 结束,耗时:$second 秒")



//返回执行结果

return second

}



}

执行结果下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

子线程:1 开始

子线程:1 结束,耗时:1

Thread 1 :拿到结果啦!是 1

子线程:2 开始

子线程:2 结束,耗时:2

Thread 2 :拿到结果啦!是 2

子线程:3 开始

Thread 3 :超时了呢,java.util.concurrent.TimeoutException

子线程:4 开始

Thread 4 :超时了呢,java.util.concurrent.TimeoutException

子线程:5 开始

Thread 5 :超时了呢,java.util.concurrent.TimeoutException

Semaphore

Semaphore通常用于子线程间争夺临界资源的场景,所以他们需要申请使用,并在使用完之后释放

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

package Concurrent



import java.util.concurrent.LinkedBlockingDeque

import java.util.concurrent.Semaphore

import java.util.concurrent.ThreadPoolExecutor

import java.util.concurrent.TimeUnit



/**

* describe: Semaphore 示例

* author: kaithmy

* date: 2018/8/10 16:27

**/

fun main(args: Array<String>) {

val threadPoolExecutor = ThreadPoolExecutor(10, 20, 10,

TimeUnit.SECONDS, LinkedBlockingDeque())



//总共有3支笔

val semaphore = Semaphore(3)



//总共5位同学

for (i in 1..5) {

threadPoolExecutor.execute(SemaphoreThread(i.toString(), semaphore))

}



}



class SemaphoreThread(var name: String, var semaphore: Semaphore) : Runnable {

override fun run() {

try {

//向老师请求一支笔

semaphore.acquire()

println("Thread $name 占用ing")

//得到笔后签名

Thread.sleep(3 * 1000L)

println("Thread $name 占用3 秒后释放")

//将笔还给老师

semaphore.release()

} catch (e: Exception) {

//这里是意外情况哦

println("Thread $name 出错啦,$e")

semaphore.release()

}

}



}

执行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Thread 1 占用ing

Thread 3 占用ing

Thread 2 占用ing

Thread 1 占用3 秒后释放

Thread 2 占用3 秒后释放

Thread 3 占用3 秒后释放

Thread 5 占用ing

Thread 4 占用ing

Thread 5 占用3 秒后释放

Thread 4 占用3 秒后释放

结语

以上就是JUC四大常用并发类的简单解释于简单用法,如果想要获取和了解更多高级用法,请手动Google和百度哦~

博主 wechat
冰糖可乐柠檬茶,可爱的女士喝点啥?喝点啥?
喜欢的话就给予一点支持吧(*/ω\*)