CountDownLatch、CyclicBarrier和Semaphore
CountDownLatch、CyclicBarrier和Semaphore這三個并發(fā)輔助類,可以在線程中呼叫,使得線程暫停等,但各有不同。
2、向不同的線程傳入CountDownLatch實例
3、如果在某一線程中呼叫await(),則此線程被掛起,直到計數(shù)器為0,才往下執(zhí)行
4、如果在某一線程中呼叫countDown(),計數(shù)器減1
5、最終如果計數(shù)器值為0時,則CountDownLatch實例不再起作用了,即為一次性的
2、向不同的線程傳入CyclicBarrier實例
3、如果在某一線程中呼叫await(),則此線程被掛起,直到計數(shù)器為0,才往下執(zhí)行
4、其他線程呼叫await(),則此線程被掛起,直到計數(shù)器為0,才往下執(zhí)行
5、最終如果計數(shù)器值為0時,則CyclicBarrier實例會將計數(shù)器值恢復(fù),又可重用
2、向不同的線程傳入Semaphore實例
3、如果在某一線程中呼叫acquire(),則Semaphore實例會將計數(shù)器值減1,如果計數(shù)器值為-1,則將計數(shù)器值置為0,此線程被掛起,直到計數(shù)器值大于1時,才往下執(zhí)行
4、此線程需呼叫release(),使得計數(shù)器值+1,以便其他線程在計數(shù)器值為0時不受阻
CountDownLatch 例子:
結(jié)果:
CyclicBarrier例子:
執(zhí)行結(jié)果:
Semaphore例子:
執(zhí)行結(jié)果:
https://www.cnblogs.com/dolphin0520/p/3920397.html
https://juejin.im/post/5aeec3ebf265da0ba76fa327
- CountDownLatch
2、向不同的線程傳入CountDownLatch實例
3、如果在某一線程中呼叫await(),則此線程被掛起,直到計數(shù)器為0,才往下執(zhí)行
4、如果在某一線程中呼叫countDown(),計數(shù)器減1
5、最終如果計數(shù)器值為0時,則CountDownLatch實例不再起作用了,即為一次性的
- CyclicBarrier
2、向不同的線程傳入CyclicBarrier實例
3、如果在某一線程中呼叫await(),則此線程被掛起,直到計數(shù)器為0,才往下執(zhí)行
4、其他線程呼叫await(),則此線程被掛起,直到計數(shù)器為0,才往下執(zhí)行
5、最終如果計數(shù)器值為0時,則CyclicBarrier實例會將計數(shù)器值恢復(fù),又可重用
- Semaphore
2、向不同的線程傳入Semaphore實例
3、如果在某一線程中呼叫acquire(),則Semaphore實例會將計數(shù)器值減1,如果計數(shù)器值為-1,則將計數(shù)器值置為0,此線程被掛起,直到計數(shù)器值大于1時,才往下執(zhí)行
4、此線程需呼叫release(),使得計數(shù)器值+1,以便其他線程在計數(shù)器值為0時不受阻
CountDownLatch 例子:
public class Test {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(2);
new Thread(){
public void run() {
try {
System.out.println("子線程"+Thread.currentThread().getName()+"正在執(zhí)行");
Thread.sleep(3000);
System.out.println("子線程"+Thread.currentThread().getName()+"執(zhí)行完畢");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
new Thread(){
public void run() {
try {
System.out.println("子線程"+Thread.currentThread().getName()+"正在執(zhí)行");
Thread.sleep(3000);
System.out.println("子線程"+Thread.currentThread().getName()+"執(zhí)行完畢");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
try {
System.out.println("等待2個子線程執(zhí)行完畢
");
latch.await();
System.out.println("2個子線程已經(jīng)執(zhí)行完畢");
System.out.println("繼續(xù)執(zhí)行主線程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(2);
new Thread(){
public void run() {
try {
System.out.println("子線程"+Thread.currentThread().getName()+"正在執(zhí)行");
Thread.sleep(3000);
System.out.println("子線程"+Thread.currentThread().getName()+"執(zhí)行完畢");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
new Thread(){
public void run() {
try {
System.out.println("子線程"+Thread.currentThread().getName()+"正在執(zhí)行");
Thread.sleep(3000);
System.out.println("子線程"+Thread.currentThread().getName()+"執(zhí)行完畢");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
try {
System.out.println("等待2個子線程執(zhí)行完畢

latch.await();
System.out.println("2個子線程已經(jīng)執(zhí)行完畢");
System.out.println("繼續(xù)執(zhí)行主線程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
結(jié)果:
線程Thread-0正在執(zhí)行
線程Thread-1正在執(zhí)行
等待2個子線程執(zhí)行完畢
線程Thread-0執(zhí)行完畢
線程Thread-1執(zhí)行完畢
2個子線程已經(jīng)執(zhí)行完畢
繼續(xù)執(zhí)行主線程
線程Thread-1正在執(zhí)行
等待2個子線程執(zhí)行完畢

線程Thread-0執(zhí)行完畢
線程Thread-1執(zhí)行完畢
2個子線程已經(jīng)執(zhí)行完畢
繼續(xù)執(zhí)行主線程
CyclicBarrier例子:
public class Test {
public static void main(String[] args) {
int N = 4;
CyclicBarrier barrier = new CyclicBarrier(N,new Runnable() {
@Override
public void run() {
System.out.println("當(dāng)前線程"+Thread.currentThread().getName());
}
});
for(int i=0;i<N;i++)
new Writer(barrier).start();
}
static class Writer extends Thread{
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("線程"+Thread.currentThread().getName()+"正在寫入數(shù)據(jù)
");
try {
Thread.sleep(5000); //以睡眠來模擬寫入數(shù)據(jù)操作
System.out.println("線程"+Thread.currentThread().getName()+"寫入數(shù)據(jù)完畢,等待其他線程寫入完畢");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
System.out.println("所有線程寫入完畢,繼續(xù)處理其他任務(wù)
");
}
}
}
public static void main(String[] args) {
int N = 4;
CyclicBarrier barrier = new CyclicBarrier(N,new Runnable() {
@Override
public void run() {
System.out.println("當(dāng)前線程"+Thread.currentThread().getName());
}
});
for(int i=0;i<N;i++)
new Writer(barrier).start();
}
static class Writer extends Thread{
private CyclicBarrier cyclicBarrier;
public Writer(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("線程"+Thread.currentThread().getName()+"正在寫入數(shù)據(jù)

try {
Thread.sleep(5000); //以睡眠來模擬寫入數(shù)據(jù)操作
System.out.println("線程"+Thread.currentThread().getName()+"寫入數(shù)據(jù)完畢,等待其他線程寫入完畢");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
System.out.println("所有線程寫入完畢,繼續(xù)處理其他任務(wù)

}
}
}
執(zhí)行結(jié)果:
線程Thread-0正在寫入數(shù)據(jù)
線程Thread-1正在寫入數(shù)據(jù)
線程Thread-2正在寫入數(shù)據(jù)
線程Thread-3正在寫入數(shù)據(jù)
線程Thread-0寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
線程Thread-1寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
線程Thread-2寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
線程Thread-3寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
當(dāng)前線程Thread-3
所有線程寫入完畢,繼續(xù)處理其他任務(wù)
所有線程寫入完畢,繼續(xù)處理其他任務(wù)
所有線程寫入完畢,繼續(xù)處理其他任務(wù)
所有線程寫入完畢,繼續(xù)處理其他任務(wù)

線程Thread-1正在寫入數(shù)據(jù)

線程Thread-2正在寫入數(shù)據(jù)

線程Thread-3正在寫入數(shù)據(jù)

線程Thread-0寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
線程Thread-1寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
線程Thread-2寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
線程Thread-3寫入數(shù)據(jù)完畢,等待其他線程寫入完畢
當(dāng)前線程Thread-3
所有線程寫入完畢,繼續(xù)處理其他任務(wù)

所有線程寫入完畢,繼續(xù)處理其他任務(wù)

所有線程寫入完畢,繼續(xù)處理其他任務(wù)

所有線程寫入完畢,繼續(xù)處理其他任務(wù)

Semaphore例子:
public class Test {
public static void main(String[] args) {
int N = 8; //工人數(shù)
Semaphore semaphore = new Semaphore(5); //機器數(shù)目
for(int i=0;i<N;i++)
new Worker(i,semaphore).start();
}
static class Worker extends Thread{
private int num;
private Semaphore semaphore;
public Worker(int num,Semaphore semaphore){
this.num = num;
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("工人"+this.num+"占用一個機器在生產(chǎn)
");
Thread.sleep(2000);
System.out.println("工人"+this.num+"釋放出機器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
int N = 8; //工人數(shù)
Semaphore semaphore = new Semaphore(5); //機器數(shù)目
for(int i=0;i<N;i++)
new Worker(i,semaphore).start();
}
static class Worker extends Thread{
private int num;
private Semaphore semaphore;
public Worker(int num,Semaphore semaphore){
this.num = num;
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("工人"+this.num+"占用一個機器在生產(chǎn)

Thread.sleep(2000);
System.out.println("工人"+this.num+"釋放出機器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
執(zhí)行結(jié)果:
工人0占用一個機器在生產(chǎn)
工人1占用一個機器在生產(chǎn)
工人2占用一個機器在生產(chǎn)
工人4占用一個機器在生產(chǎn)
工人5占用一個機器在生產(chǎn)
工人0釋放出機器
工人2釋放出機器
工人3占用一個機器在生產(chǎn)
工人7占用一個機器在生產(chǎn)
工人4釋放出機器
工人5釋放出機器
工人1釋放出機器
工人6占用一個機器在生產(chǎn)
工人3釋放出機器
工人7釋放出機器
工人6釋放出機器

工人1占用一個機器在生產(chǎn)

工人2占用一個機器在生產(chǎn)

工人4占用一個機器在生產(chǎn)

工人5占用一個機器在生產(chǎn)

工人0釋放出機器
工人2釋放出機器
工人3占用一個機器在生產(chǎn)

工人7占用一個機器在生產(chǎn)

工人4釋放出機器
工人5釋放出機器
工人1釋放出機器
工人6占用一個機器在生產(chǎn)

工人3釋放出機器
工人7釋放出機器
工人6釋放出機器
https://www.cnblogs.com/dolphin0520/p/3920397.html
posted on 2019-09-24 10:18 paulwong 閱讀(336) 評論(0) 編輯 收藏 所屬分類: J2SE