问题描述
有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所产生的产品放入缓冲区中,消费者进程可以从一个缓冲区中取走产品去消费。尽管所有的生产者和消费者进程都是以异步的方式运行的,但他们之间必须保持同步,即不允许消费者进程到一个空的缓冲区中去取产品,也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区投放产品。
代码
package time20180914;
import java.util.ArrayList;
public class Two {
public static void main(String[] args) {
//缓冲池
ArrayList<Integer> a = new ArrayList<Integer>(5);
//启动生产者
new Thread(new producter(a)).start()
//启动消费者;
new Thread(new Consumer(a)).start();
}
}
class producter implements Runnable {
ArrayList<Integer> a;
public producter(ArrayList<Integer> a) {
this.a = a;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//对缓冲池加锁
synchronized (a) {
//进行判断
if(a.size()<5){
a.add(1);
System.out.println("正在生产,当前剩余"+a.size());
//当生产过后要通知一下消费者可以取了
a.notifyAll();
}else {
System.out.println("产量太多进入等待");
try {
//当满了以后要注意等待
a.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class Consumer implements Runnable {
ArrayList<Integer> a;
public Consumer(ArrayList<Integer> a) {
this.a = a;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a) {
if(a.size()>0){
a.remove(0);
System.out.println("消费了,当前剩余"+a.size());
//通知生产者生产
a.notifyAll();
}else {
System.out.println("产量不足,进入等待");
try {
//当缓冲池空的时候要等待
a.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
package time20180914;
import java.util.ArrayList;
public class Two {
public static void main(String[] args) {
//缓冲池
ArrayList<Integer> a = new ArrayList<Integer>(5);
//启动生产者
new Thread(new producter(a)).start()
//启动消费者;
new Thread(new Consumer(a)).start();
}
}
class producter implements Runnable {
ArrayList<Integer> a;
public producter(ArrayList<Integer> a) {
this.a = a;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//对缓冲池加锁
synchronized (a) {
//进行判断
if(a.size()<5){
a.add(1);
System.out.println("正在生产,当前剩余"+a.size());
//当生产过后要通知一下消费者可以取了
a.notifyAll();
}else {
System.out.println("产量太多进入等待");
try {
//当满了以后要注意等待
a.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class Consumer implements Runnable {
ArrayList<Integer> a;
public Consumer(ArrayList<Integer> a) {
this.a = a;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a) {
if(a.size()>0){
a.remove(0);
System.out.println("消费了,当前剩余"+a.size());
//通知生产者生产
a.notifyAll();
}else {
System.out.println("产量不足,进入等待");
try {
//当缓冲池空的时候要等待
a.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
第二种实现方式
直接通过一个资源池来进行资源的调配
package time20180914;
//wait 和 notify
public class ProducerConsumerWithWaitNofity {
public static void main(String[] args) {
Resource resource = new Resource();
//生产者线程
ProducerThread p1 = new ProducerThread(resource);
// ProducerThread p2 = new ProducerThread(resource);
// ProducerThread p3 = new ProducerThread(resource);
//消费者线程
ConsumerThread c1 = new ConsumerThread(resource);
//ConsumerThread c2 = new ConsumerThread(resource);
//ConsumerThread c3 = new ConsumerThread(resource);
p1.start();
// p2.start();
// p3.start();
c1.start();
//c2.start();
//c3.start();
}
}
/**
* 公共资源类
* @author
*
*/
class Resource{//重要
//当前资源数量
private int num = 0;
//资源池中允许存放的资源数目
private int size = 10;
/**
* 从资源池中取走资源
*/
public synchronized void remove(){
if(num > 0){
num--;
System.out.println("消费者" + Thread.currentThread().getName() +
"消耗一件资源," + "当前线程池有" + num + "个");
notifyAll();//通知生产者生产资源
}else{
try {
//如果没有资源,则消费者进入等待状态
wait();
System.out.println("消费者" + Thread.currentThread().getName() + "线程进入等待状态");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 向资源池中添加资源
*/
public synchronized void add(){
if(num < size){
num++;
System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有"
+ num + "个");
//通知等待的消费者
notifyAll();
}else{
//如果当前资源池中有10件资源
try{
wait();//生产者进入等待状态,并释放锁
System.out.println(Thread.currentThread().getName()+"线程进入等待");
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
/**
* 消费者线程
*/
class ConsumerThread extends Thread{
private Resource resource;
public ConsumerThread(Resource resource){
this.resource = resource;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
resource.remove();
}
}
}
/**
* 生产者线程
*/
class ProducerThread extends Thread{
private Resource resource;
public ProducerThread(Resource resource){
this.resource = resource;
}
@Override
public void run() {
//不断地生产资源
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
resource.add();
}
}
}
package time20180914;
//wait 和 notify
public class ProducerConsumerWithWaitNofity {
public static void main(String[] args) {
Resource resource = new Resource();
//生产者线程
ProducerThread p1 = new ProducerThread(resource);
// ProducerThread p2 = new ProducerThread(resource);
// ProducerThread p3 = new ProducerThread(resource);
//消费者线程
ConsumerThread c1 = new ConsumerThread(resource);
//ConsumerThread c2 = new ConsumerThread(resource);
//ConsumerThread c3 = new ConsumerThread(resource);
p1.start();
// p2.start();
// p3.start();
c1.start();
//c2.start();
//c3.start();
}
}
/**
* 公共资源类
* @author
*
*/
class Resource{//重要
//当前资源数量
private int num = 0;
//资源池中允许存放的资源数目
private int size = 10;
/**
* 从资源池中取走资源
*/
public synchronized void remove(){
if(num > 0){
num--;
System.out.println("消费者" + Thread.currentThread().getName() +
"消耗一件资源," + "当前线程池有" + num + "个");
notifyAll();//通知生产者生产资源
}else{
try {
//如果没有资源,则消费者进入等待状态
wait();
System.out.println("消费者" + Thread.currentThread().getName() + "线程进入等待状态");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 向资源池中添加资源
*/
public synchronized void add(){
if(num < size){
num++;
System.out.println(Thread.currentThread().getName() + "生产一件资源,当前资源池有"
+ num + "个");
//通知等待的消费者
notifyAll();
}else{
//如果当前资源池中有10件资源
try{
wait();//生产者进入等待状态,并释放锁
System.out.println(Thread.currentThread().getName()+"线程进入等待");
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
/**
* 消费者线程
*/
class ConsumerThread extends Thread{
private Resource resource;
public ConsumerThread(Resource resource){
this.resource = resource;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
resource.remove();
}
}
}
/**
* 生产者线程
*/
class ProducerThread extends Thread{
private Resource resource;
public ProducerThread(Resource resource){
this.resource = resource;
}
@Override
public void run() {
//不断地生产资源
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
resource.add();
}
}
}