padding: 15px 15px 15px 1rem;
font-size: 0.9em;
margin: 1em 0px;
color: rgb(0, 0, 0);
border-left: 5px solid rgb(239, 112, 96);
background: rgb(239, 235, 233);
overflow: auto;
overflow-wrap: normal;
word-break: normal;
“> color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.7em 0px;
“>talk is cheap,show me the code color: inherit;
line-height: inherit;
padding: 0px;
margin: 0px;
“>JUC其實是屬於執行緒知識的中高階部分,所以也是面試中面試官喜歡問的一塊知識點,這塊知識也能比較看出一個程式設計師的功底,今天筆者就跟大家講講CountDownLatch,CyclicBarrier,Semaphore這些知識點。大家在看到這些知識的時候,千萬不要一上來就摳細節,首先應該弄明白這些知識點時是幹什麼用的,用來解決什麼問題,適合應用於什麼樣的業務場景。如果這些東西都沒搞清楚就學,那麼你學完很快就會忘掉。 line-height: inherit;
margin: 0px;
display: inline-block;
font-weight: normal;
background: rgb(239, 112, 96);
color: rgb(255, 255, 255);
padding: 3px 10px 1px;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
margin-right: 3px;
“>閉鎖CountDownLatch display: block;
padding: 15px 15px 15px 1rem;
font-size: 0.9em;
margin: 1em 0px;
color: rgb(0, 0, 0);
border-left: 5px solid rgb(239, 112, 96);
background: rgb(239, 235, 233);
overflow: auto;
overflow-wrap: normal;
word-break: normal;
“>
color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
"> 1package
com.bingo.thread.juc;
2
3/**
4
*
Created
with
IntelliJ
IDEA.
5
*
Description:
倒時計數器(也叫閉鎖)
6
*
User:
bingo
7
*
Date:
2018-11-25
8
*
Time:
11:16
9
*/
10import
java.util.concurrent.CountDownLatch;
11import
java.util.concurrent.ExecutorService;
12import
java.util.concurrent.Executors;
13
14public
class
CountDownLatchDemo
{
15
16
public
static
void
main(String[]args)
throws
InterruptedException{
17
final
CountDownLatch
startGate=new
CountDownLatch(1);
18
final
CountDownLatch
endGate=new
CountDownLatch(5);
19
//執行緒池
20
ExecutorService
exce=Executors.newCachedThreadPool();
21
//建立5個執行緒
22
for(int
i=1;
i<
=5;
i++){
23
final
int
num=i;
24
Thread
thread
=new
Thread(new
Runnable()
{
25
public
void
run()
{
26
try
{
27
System.out.println(num+"號選手準備就緒,等待裁判員哨聲響起..");
28
//相當於同步鎖Synchronized中的await()方法
29
startGate.await();
30
try
{
31
Thread.sleep((long)
(Math.random()*10000));
32
}
catch
(InterruptedException
e)
{
33
e.printStackTrace();
34
}
35
System.out.println(num+"號選手到達終點..");
36
}
catch
(InterruptedException
e)
{
37
e.printStackTrace();
38
}
39
finally{
40
//相當於同步鎖Synchronized中的notify()方法,區別在於countDown需要執行5次後才能喚醒await()
41
endGate.countDown();
42
}
43
}
44
});
45
exce.execute(thread);
46
}
47
long
start=System.nanoTime();
48
System.out.println("裁判員哨聲響起..");
49
Thread.sleep(10000);
50
//喚醒執行startGate.await()的執行緒,讓執行緒往下執行
51
startGate.countDown();
52
//等待被喚醒,主程式才能繼續往下執行,執行緒中每次執行endGate.countDown()就減1,當為零的時候,主程式往下執行
53
endGate.await();
54
long
end=System.nanoTime();
55
System.out.println("所有運動員到達終點,耗時:"+(end-start));
56
//關閉執行緒池
57
exce.shutdown();
58
}
59
}
複製程式碼
line-height: inherit;
margin: 0px;
padding: 0px;
“>執行結果
1裁判員哨聲響起..
21號選手準備就緒,等待裁判員哨聲響起..
32號選手準備就緒,等待裁判員哨聲響起..
43號選手準備就緒,等待裁判員哨聲響起..
54號選手準備就緒,等待裁判員哨聲響起..
65號選手準備就緒,等待裁判員哨聲響起..
73號選手到達終點..
81號選手到達終點..
94號選手到達終點..
105號選手到達終點..
112號選手到達終點..
12所有運動員到達終點,耗時:17708083042
13
14Process
finished
with
exit
code
0
複製程式碼
color: inherit;line-height: inherit;
margin: 0px;
padding: 0px;
“>CountDownLatch實時系統中的使用場景
line-height: inherit;
margin: 0px;
padding: 0px;
margin-bottom: 0.5em;
“> color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
margin-bottom: 0.5em;
“> color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
margin-bottom: 0.5em;
“> line-height: inherit;
margin: 0px;
display: inline-block;
font-weight: normal;
background: rgb(239, 112, 96);
color: rgb(255, 255, 255);
padding: 3px 10px 1px;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
margin-right: 3px;
“>迴圈屏障CyclicBarrier display: block;
padding: 15px 15px 15px 1rem;
font-size: 0.9em;
margin: 1em 0px;
color: rgb(0, 0, 0);
border-left: 5px solid rgb(239, 112, 96);
background: rgb(239, 235, 233);
overflow: auto;
overflow-wrap: normal;
word-break: normal;
“> color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.7em 0px;
“> 需求:人們(執行緒)先後到達餐桌上(某個點),但是不能動筷子(等待),所有人到齊才可以吃年夜飯(執行緒到齊才能一同執行)
1package
com.bingo.thread.juc;
2
3import
java.util.concurrent.BrokenBarrierException;
4import
java.util.concurrent.CyclicBarrier;
5
6public
class
CyclicBarrierDemo
{
7
8
public
static
void
main(String[]
args)
{
9
final
int
count
=
5;
10
final
CyclicBarrier
barrier
=
new
CyclicBarrier(count,
new
Runnable()
{
11
@Override
12
public
void
run()
{
13
System.out.println("人到齊,大家一起吃年夜飯!");
14
}
15
});
16
17
//
they
do
not
have
to
start
at
the
same
time...
18
for
(int
i
=
0;
i
<
count;
i++)
{
19
new
Thread(new
Worker(i,
barrier)).start();
20
}
21
}
22
}
23
24class
Worker
implements
Runnable
{
25
final
int
id;
26
final
CyclicBarrier
barrier;
27
28
public
Worker(final
int
id,
final
CyclicBarrier
barrier)
{
29
this.id
=
id;
30
this.barrier
=
barrier;
31
}
32
33
@Override
34
public
void
run()
{
35
try
{
36
System.out.println(this.id
+
"starts
to
run
!");
37
Thread.sleep((long)
(Math.random()
*
10000));
38
System.out.println(this.id
+
"到桌
!");
39
this.barrier.await();
40
}
catch
(InterruptedException
e)
{
41
e.printStackTrace();
42
}
catch
(BrokenBarrierException
e)
{
43
e.printStackTrace();
44
}
45
}
46
}
複製程式碼
color: inherit;line-height: inherit;
margin: 0px;
padding: 0px;
“>執行結果
10starts
to
run
!
22starts
to
run
!
31starts
to
run
!
43starts
to
run
!
54starts
to
run
!
64到桌
!
73到桌
!
81到桌
!
92到桌
!
100到桌
!
11人到齊,大家一起吃年夜飯!
12
13Process
finished
with
exit
code
0
複製程式碼
line-height: inherit;margin: 0px;
display: inline-block;
font-weight: normal;
background: rgb(239, 112, 96);
color: rgb(255, 255, 255);
padding: 3px 10px 1px;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
margin-right: 3px;
“>區別 color: inherit;
line-height: inherit;
margin: 0px;
padding: 0px;
padding-left: 32px;
list-style-type: disc;
“>
line-height: inherit;
margin: 0px;
padding: 0px;
“>CountDownLatch減計數,CyclicBarrier加計數。
line-height: inherit;
margin: 0px;
padding: 0px;
“>CountDownLatch是一次性的,CyclicBarrier可以重用。 line-height: inherit;
margin: 0px;
display: inline-block;
font-weight: normal;
background: rgb(239, 112, 96);
color: rgb(255, 255, 255);
padding: 3px 10px 1px;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
margin-right: 3px;
“>訊號量Semaphore display: block;
padding: 15px 15px 15px 1rem;
font-size: 0.9em;
margin: 1em 0px;
color: rgb(0, 0, 0);
border-left: 5px solid rgb(239, 112, 96);
background: rgb(239, 235, 233);
overflow: auto;
overflow-wrap: normal;
word-break: normal;
“> color: inherit;
line-height: inherit;
padding: 0px;
margin: 1.7em 0px;
“> 需求:假如現在網咖有5臺電腦,但是現在有8個人進入網咖,同一時間只能有5個人上機,而其中三個人主要等到其他人空出電腦的時候才能上機。
這時Semaphore就派上用場了。
1package
com.bingo.thread.juc;
2
3import
java.util.concurrent.Semaphore;
4
5public
class
SemaphoreDemo
{
6
public
static
void
main(String[]
args)
{
7
int
N
=
8;
//學生數
8
Semaphore
semaphore
=
new
Semaphore(5);
//電腦數目
9
for(int
i=0;
i<
N;
i++)
10
new
Worker(i,semaphore).start();
11
}
12
13
static
class
Worker
extends
Thread{
14
private
int
num;
15
private
Semaphore
semaphore;
16
public
Worker(int
num,Semaphore
semaphore){
17
this.num
=
num;
18
this.semaphore
=
semaphore;
19
}
20
21
@Override
22
public
void
run()
{
23
try
{
24
semaphore.acquire();
25
System.out.println("同學"+this.num+"佔用一臺電腦...");
26
Thread.sleep(2000);
27
System.out.println("--同學"+this.num+"離開電腦");
28
semaphore.release();
29
}
catch
(InterruptedException
e)
{
30
e.printStackTrace();
31
}
32
}
33
}
34
}
複製程式碼
color: inherit;line-height: inherit;
margin: 0px;
padding: 0px;
“>執行結果
1同學0佔用一臺電腦...
2同學1佔用一臺電腦...
3同學2佔用一臺電腦...
4同學3佔用一臺電腦...
5同學4佔用一臺電腦...
6--同學0離開電腦
7--同學1離開電腦
8--同學4離開電腦
9--同學3離開電腦
10同學7佔用一臺電腦...
11--同學2離開電腦
12同學6佔用一臺電腦...
13同學5佔用一臺電腦...
14--同學7離開電腦
15--同學5離開電腦
16--同學6離開電腦
17
18Process
finished
with
exit
code
0
複製程式碼
https://juejin.im/post/5bfcb99cf265da613e21edd5