首页 / JAVA / java并发之生产者消费者模型
java并发之生产者消费者模型
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java并发之生产者消费者模型,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3874字,纯文字阅读大概需要6分钟。
内容图文
![java并发之生产者消费者模型](/upload/InfoBanner/zyjiaocheng/1152/d376fcf77bac433283e89192b1b0b38f.jpg)
生产者和消费者模型是操作系统中经典的同步问题。该问题最早由Dijkstra提出,用以演示它提出的信号量机制。
经典的生产者和消费者模型的描写叙述是:有一群生产者进程在生产产品。并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区中。消费者进程可从一个缓冲区中取走产品去消费。虽然全部的生产者进程和消费者进程都是以异步方式执行的。但它们之间必须保持同步,即不同意消费者进程到一个空缓冲区去取产品,也不同意生产者进程向一个已装满产品且尚未被取走的缓冲区投放产品。
首先我们复习一下操作系统中同步机制中应遵循的准则:
- 空暇让进:当无进程处于临界区时,应同意一个请求进入临界区的进程进入临界区;
- 忙则等待:当已有进程进入临界区时,其它试图进入临界区的进程必须等待。
- 有限等待:对要求訪问临界资源的进程,应保证在有限时间内能进入自己的临界区。以免陷入“死等”状态。
-
让权等待:当进程不能进入自己的临界区时,应马上释放处理机。以免进程陷入“忙等”;
在生产者和消费者模型中要保证一下几点:
1.生产者在往缓存队列中放产品时,消费者不能取产品。
2.消费者从缓存队列中取产品时。生产者不能放产品。
3.同一时刻仅仅有一个生产者能够往缓存队列中放产品。
4.同一时刻仅仅有一个消费者能够从缓存队列中取产品。
5.缓存队列满时生产者不能往缓存队列中放产品。
6.缓存队列为空时消费者不能从缓存队列中取产品。
本样例中的缓存队列模仿java jdk中的ArrayBlockingQueue,这是一个堵塞队列,缓存池满时会自己主动将生产者线程挂起,缓存池空时会自己主动将消费者线程挂起。
缓存池
public classPool<E> {/**队列最长长度*/private int MaxSize = 1000;
/**队列默认长度*/private static final int defaultSize = 100;
/**资源池*/private Object[] objs ;
/**队头*/private int front;
/**队尾*/private int rear;
/**元素的个数*/private int nItems;
/** Main lock guarding all access */final ReentrantLock lock;
/** Condition for waiting takes */privatefinal Condition notEmpty;
/** Condition for waiting puts */privatefinal Condition notFull;
private int useSize = 0;
public Pool() {
this(defaultSize);
useSize = defaultSize;
}
public Pool(int size) {
if(size < 0)
thrownew IndexOutOfBoundsException();
size = size > MaxSize ? MaxSize : size;
useSize = size;
objs = new Object[size];
front = 0;
rear = -1;
nItems = 0;
lock = new ReentrantLock(true);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
/**进队*/private void queue(E e) {
if(rear == useSize - 1)
rear = -1;
objs[++rear] = e;
nItems++;
notEmpty.signal();
}
/**出队*/private E dequeue() {
E e = (E)objs[front++];
if(front == useSize)
front = 0;
nItems--;
notFull.signal();
return e;
}
/**进队 资源池满会将入队线程挂起*/
public void offer(E e) throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lock();
try {
while(nItems == objs.length)
notFull.await();
queue(e);
System.out.println("学生进队。当前池中有 " + nItems + " 名同学" );
} finally {
lock.unlock();
}
}
/**出队 资源池空会将出队线程挂起*/
public E poll() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lock();
try {
while(nItems == 0)
notEmpty.await();
E e = dequeue();
System.out.println("学生出队,当前池中有 " + nItems + " 名同学" );
return e;
} finally {
lock.unlock();
}
}
/**是否满*/
public boolean isFull() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return nItems == MaxSize ? true : false;
} finally {
lock.unlock();
}
}
/**推断是否为空*/
public boolean isEmpty() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return nItems == 0 ? true : false;
} finally {
lock.unlock();
}
}
/**返回队列中元素个数*/
public int size() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
returnthis.nItems;
} finally {
lock.unlock();
}
}
}
測试模型
public
class Student {
private String name;
privateint age;
public String getName() {
return name;
}
publicvoidsetName(String name) {
this.name = name;
}
publicintgetAge() {
return age;
}
publicvoidsetAge(int age) {
this.age = age;
}
}
主类
public
class
PM {
private Pool<Student> pools = new Pool<Student>(1000);
publicstaticvoid main(String[] args) {
PM pm = new PM();
ExecutorService executor = Executors.newFixedThreadPool(6);
executor.execute(pm.new consume());
executor.execute(pm.new consume());
executor.execute(pm.new consume());
executor.execute(pm.new produce());
executor.execute(pm.new produce());
executor.execute(pm.new produce());
}
classproduceimplementsRunnable {
@Override
publicvoid run() {
while(true) {
try {
pools.offer(new Student());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
classconsumeimplementsRunnable {
@Override
publicvoid run() {
while(true) {
try {
pools.poll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
执行结果:
原文:https://www.cnblogs.com/zhchoutai/p/8323443.html
内容总结
以上是互联网集市为您收集整理的java并发之生产者消费者模型全部内容,希望文章能够帮你解决java并发之生产者消费者模型所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。