手撕一个生产者消费者模型

生产者-消费者模型是在计算机各个领域经常用到的一个模型,那么如何简单实现这个模型呢?


问题分析

  • 首先,需要一个地方存放生产者生产与消费者消费的资源,简单起见我们用一个Object数组当做资源池来保存资源。

  • 其次,我们知道资源池是有大小限制的,那么生产者向资源池添加资源时就必须考虑资源池是否填满。同理,消费者消费资源时也必须考虑资源池里有没有资源可供消费,即资源池是否为空。那么我们如何知道资源池是满还是空呢?当然是给资源池添加两个属性来表示资源池的状态:notFull表示非满状态,notEmpty表示非空状态。

  • 最后,资源池是一个临界资源,不能同时被生产者消费者访问(存在多个生产者和消费者。若同时访问会造成资源数据错误)。我们需要一把锁来控制资源池的访问。这里采用ReentryLock来进行访问控制。
  • 综上,采用带两个条件的ReentryLock来实现生产者消费者模型最合适不过了。下面就是实现代码。

生产者-消费者模型代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class <T> {
private Object[] resources;
大专栏  手撕一个生产者消费者模型>
private int addIndex, removeIndex, count;
private Lock lock = new ReentryLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();

public (int size){
resources = new Object[size];
}

//生产者生产资源,若资源池已满,则生产者进入等待状态,直到有空位
public void addResource(T resource) throws InterruptedException{
lock.lock();
try{
while(count==Object.length){
notFull.await();
}
resources[addIndex] = resource;
if(++addIndex==Object.length){
addIndex = 0;
}
++count;
notEmpty.signal();
}finally{
lock.unlock();
}
}

//消费者消费资源,若资源池为空,则消费者进入等待状态,直到资源池有资源
public T removeResource(){
lock.lock();
try{
while(count==0){
notEmpty.await();
}
Object resource = resources[removeIndex];
if(++removeIndex==resources.length){
removeIndex==0;
}
--count;
notFull.signal();
return (T) resource;
}finally{
lock.unlock();
}
}
}

猜你喜欢

转载自www.cnblogs.com/liuzhongrong/p/12365271.html