生產者-消費者(producer-consumer)問題,也稱作有界緩沖區(bounded-buffer)問題,兩個進程共享一個公共的固定大小的緩沖區。其中一個是生產者,用於將消息放入緩沖區;另外一個是消費者,用於從緩沖區中取出消息。問題出現在當緩沖區已經滿了,而此時生產者還想向其中放入一個新的數據項的情形,其解決方法是讓生產者此時進行休眠,等待消費者從緩沖區中取走了一個或者多個數據後再去喚醒它。同樣地,當緩沖區已經空了,而消費者還想去取消息,此時也可以讓消費者進行休眠,等待生產者放入一個或者多個數據時再喚醒它。
一,首先定義公共資源類,其中的變量number是保存的公共數據。
並且定義兩個方法,增加number的值和減少number的值。由於多線程的原因,必須加上synchronized關鍵字,注意while判斷的條件。
Java代碼
二,分別定義生產
/**
* 公共資源類
*/
public class PublicResource {
private int number = 0;
/**
* 增加公共資源
*/
public synchronized void increace() {
while (number != 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number++;
System.out.println(number);
notify();
}
/**
* 減少公共資源
*/
public synchronized void decreace() {
while (number == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number--;
System.out.println(number);
notify();
}
}
者線程和消費者線程,並模擬多次生產和消費,即增加和減少公共資源的number值
Java代碼
/**
* 生產者線程,負責生產公共資源
*/
public class ProducerThread implements Runnable {
private PublicResource resource;
public ProducerThread(PublicResource resource) {
this.resource = resource;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
resource.increace();
}
}
}
/**
* 消費者線程,負責消費公共資源
*/
public class ConsumerThread implements Runnable {
private PublicResource resource;
public ConsumerThread(PublicResource resource) {
this.resource = resource;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
resource.decreace();
}
}
}
三,模擬多個生產者和消費者操作公共資源的情形,結果須保證是在允許的范圍內。
Java代碼
public class ProducerConsumerTest {
public static void main(String[] args) {
PublicResource resource = new PublicResource();
new Thread(new ProducerThread(resource)).start();
new Thread(new ConsumerThread(resource)).start();
new Thread(new ProducerThread(resource)).start();
new Thread(new ConsumerThread(resource)).start();
new Thread(new ProducerThread(resource)).start();
new Thread(new ConsumerThread(resource)).start();
}
}
以上所述是小編給大家介紹的Java生產者和消費者例子,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對網站的支持!