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

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

線程Thread-0執行完畢
線程Thread-1執行完畢
2個子線程已經執行完畢
繼續執行主線程
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("當前線程"+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()+"正在寫入數據
");
try {
Thread.sleep(5000); //以睡眠來模擬寫入數據操作
System.out.println("線程"+Thread.currentThread().getName()+"寫入數據完畢,等待其他線程寫入完畢");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
}catch(BrokenBarrierException e){
e.printStackTrace();
}
System.out.println("所有線程寫入完畢,繼續處理其他任務
");
}
}
}
public static void main(String[] args) {
int N = 4;
CyclicBarrier barrier = new CyclicBarrier(N,new Runnable() {
@Override
public void run() {
System.out.println("當前線程"+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()+"正在寫入數據

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

}
}
}
執行結果:
線程Thread-0正在寫入數據
線程Thread-1正在寫入數據
線程Thread-2正在寫入數據
線程Thread-3正在寫入數據
線程Thread-0寫入數據完畢,等待其他線程寫入完畢
線程Thread-1寫入數據完畢,等待其他線程寫入完畢
線程Thread-2寫入數據完畢,等待其他線程寫入完畢
線程Thread-3寫入數據完畢,等待其他線程寫入完畢
當前線程Thread-3
所有線程寫入完畢,繼續處理其他任務
所有線程寫入完畢,繼續處理其他任務
所有線程寫入完畢,繼續處理其他任務
所有線程寫入完畢,繼續處理其他任務

線程Thread-1正在寫入數據

線程Thread-2正在寫入數據

線程Thread-3正在寫入數據

線程Thread-0寫入數據完畢,等待其他線程寫入完畢
線程Thread-1寫入數據完畢,等待其他線程寫入完畢
線程Thread-2寫入數據完畢,等待其他線程寫入完畢
線程Thread-3寫入數據完畢,等待其他線程寫入完畢
當前線程Thread-3
所有線程寫入完畢,繼續處理其他任務

所有線程寫入完畢,繼續處理其他任務

所有線程寫入完畢,繼續處理其他任務

所有線程寫入完畢,繼續處理其他任務

Semaphore例子:
public class Test {
public static void main(String[] args) {
int N = 8; //工人數
Semaphore semaphore = new Semaphore(5); //機器數目
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+"占用一個機器在生產
");
Thread.sleep(2000);
System.out.println("工人"+this.num+"釋放出機器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
int N = 8; //工人數
Semaphore semaphore = new Semaphore(5); //機器數目
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+"占用一個機器在生產

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

工人1占用一個機器在生產

工人2占用一個機器在生產

工人4占用一個機器在生產

工人5占用一個機器在生產

工人0釋放出機器
工人2釋放出機器
工人3占用一個機器在生產

工人7占用一個機器在生產

工人4釋放出機器
工人5釋放出機器
工人1釋放出機器
工人6占用一個機器在生產

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