Lock、Condition實(shí)現(xiàn)簡(jiǎn)單的生產(chǎn)者消費(fèi)者模式示例
package condition;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 利用Lock、Condition實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模式
* @author will
*
*/
public class ProducerConsumerDemo {
public static void main(String[] args) {
int producerCount = 10;
int consumerCount = 15;
final ProducerConsumerDemo pcd = new ProducerConsumerDemo(5); // 緩沖區(qū)大小為5
Thread[] producerThreads = new Thread[producerCount];
for(int i = 0; i < producerCount; i++) {
producerThreads[i] = new Thread("producer" + (i+1)) {
@Override
public void run() {
pcd.produce();
}
};
}
Thread[] consumerThreads = new Thread[consumerCount];
for(int j = 0; j < consumerCount; j++) {
consumerThreads[j] = new Thread("consumer" + (j+1)) {
@Override
public void run() {
pcd.consume();
}
};
}
// 啟動(dòng)生產(chǎn)者消費(fèi)者線(xiàn)程
for(int i = 0; i < producerCount; i++) {
producerThreads[i].start();
}
for(int j = 0; j < consumerCount; j++) {
consumerThreads[j].start();
}
}
private static final int DEFAULT_BUFFER_SIZE = 10;
private int bufferSize; // 緩沖區(qū)大小
private List<Object> bufferList;
private final Lock lock = new ReentrantLock(true);
private final Condition condition = lock.newCondition();
public ProducerConsumerDemo(int bufferSize) {
this.bufferSize = bufferSize > 0 ? bufferSize : DEFAULT_BUFFER_SIZE;
bufferList = new ArrayList<Object>(bufferSize);
}
// 生產(chǎn)
public void produce() {
lock.lock(); // 加鎖
try {
while(bufferList.size() == bufferSize) { // 緩沖區(qū)滿(mǎn)了
System.out.println("Producer wait, thread: " + Thread.currentThread().getName());
condition.await();
}
// 生產(chǎn)
bufferList.add(new Object());
System.out.println("Producer produce one, now buffer size: "
+ bufferList.size() + ", and thread: " + Thread.currentThread().getName());
condition.signalAll(); // 通知消費(fèi)者
} catch(InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
// 消費(fèi)
public void consume() {
lock.lock(); // 加鎖
try {
while(bufferList.isEmpty()) { // 緩沖區(qū)空了
System.out.println("Consumer wait, thread: " + Thread.currentThread().getName());
condition.await();
}
// 消費(fèi)
bufferList.remove(0); // 從鏈表頭部移除一個(gè)
System.out.println("Consumer consumer one, now buffer size: "
+ bufferList.size() + ", and thread: " + Thread.currentThread().getName());
condition.signalAll();
} catch(InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
相關(guān)文章
詳解Java ES多節(jié)點(diǎn)任務(wù)的高效分發(fā)與收集實(shí)現(xiàn)
ElasticSearch 是一個(gè)高可用開(kāi)源全文檢索和分析組件。提供存儲(chǔ)服務(wù),搜索服務(wù),大數(shù)據(jù)準(zhǔn)實(shí)時(shí)分析等。一般用于提供一些提供復(fù)雜搜索的應(yīng)用2021-06-06SpringMVC使用@Valid注解實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證的代碼示例
在 Web 開(kāi)發(fā)中,數(shù)據(jù)驗(yàn)證是一個(gè)非常重要的環(huán)節(jié),它可以確保數(shù)據(jù)的合法性和正確性,保護(hù)系統(tǒng)不受到惡意攻擊或用戶(hù)誤操作的影響,在 SpringMVC 中,我們可以使用 @Valid 注解來(lái)實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證,所以本文就給大家介紹具體的使用方法,需要的朋友可以參考下2023-07-07Java web實(shí)現(xiàn)賬號(hào)單一登錄,防止同一賬號(hào)重復(fù)登錄(踢人效果)
這篇文章主要介紹了Java web實(shí)現(xiàn)賬號(hào)單一登錄,防止同一賬號(hào)重復(fù)登錄,有點(diǎn)類(lèi)似于qq登錄踢人效果,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-10-10簡(jiǎn)述Java中進(jìn)程與線(xiàn)程的關(guān)系_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
在 Java 語(yǔ)言中,對(duì)進(jìn)程和線(xiàn)程的封裝,分別提供了 Process 和 Thread 相關(guān)的一些類(lèi)。本文首先簡(jiǎn)單的介紹如何使用這些類(lèi)來(lái)創(chuàng)建進(jìn)程和線(xiàn)程2017-05-05Springboot通過(guò)Scheduled實(shí)現(xiàn)定時(shí)任務(wù)代碼
這篇文章主要介紹了Springboot通過(guò)Scheduled實(shí)現(xiàn)定時(shí)任務(wù)代碼,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11Struts2 Result 返回JSON對(duì)象詳解
這篇文章主要講解Struts2返回JSON對(duì)象的兩種方式,講的比較詳細(xì),希望能給大家做一個(gè)參考。2016-06-06淺談Springmvc中的頁(yè)面跳轉(zhuǎn)問(wèn)題
這篇文章主要介紹了淺談Springmvc中的頁(yè)面跳轉(zhuǎn)問(wèn)題,具有一定參考價(jià)值,需要的朋友可以了解下。2017-12-12elasticsearch索引創(chuàng)建create?index集群matedata更新
這篇文章主要介紹了elasticsearch索引創(chuàng)建create?index及集群matedata更新,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04