使用ReentrantLock以及Condition实现的生产者消费者,也是java 1.5之后推荐写法,不再使用object类的notify()以及wait()方法。直接上代码:
public class Stroge {
private final int MAX_SIZE = 100;
private LinkedList<Object> list = new LinkedList<>();
private Lock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();
public void produce(int num) {
lock.lock();
try {
while (list.size() + num > MAX_SIZE) {
System.out.println("当前size:" + list.size() + ",不能再创建" + num + "个产品,await");
try {
notFull.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < num; i++) {
list.add(new Object());
}
System.out.println(num + "个产品创建完成,当前size:" + list.size());
notEmpty.signalAll();
} finally {
lock.unlock();
}
}
public void consume(int num) {
lock.lock();
try {
while (list.size() < num) {
System.out.println("当前size:" + list.size() + ",不能再消费" + num + "个产品,await");
try {
notEmpty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < num; i++) {
list.remove();
}
System.out.println(num + "个产品消费完成,当前size:" + list.size());
notFull.signalAll();
} finally {
lock.unlock();
}
}
}
//生产者类
class Producter extends Thread {
Stroge sto = null;
private int num;
public Producter(Stroge sto) {
this.sto = sto;
}
public void setNum(int num) {
this.num = num;
}
public void product(int num) {
sto.produce(num);
}
@Override
public void run() {
product(num);
}
}
//消费者类
class Consumer extends Thread {
Stroge sto = null;
private int num;
public Consumer(Stroge sto) {
this.sto = sto;
}
public void setNum(int num) {
this.num = num;
}
public void consume(int num) {
sto.consume(num);
}
@Override
public void run() {
consume(num);
}
}
测试类:
public class Testprosum {
public static void main(String[] args) {
Stroge sto = new Stroge();
Producter p1 = new Producter(sto);
Producter p2 = new Producter(sto);
Producter p3 = new Producter(sto);
Producter p4 = new Producter(sto);
Producter p5 = new Producter(sto);
Consumer c1 = new Consumer(sto);
Consumer c2 = new Consumer(sto);
Consumer c3 = new Consumer(sto);
Consumer c4 = new Consumer(sto);
Consumer c5 = new Consumer(sto);
p1.setNum(10);
p2.setNum(20);
p3.setNum(30);
p4.setNum(40);
p5.setNum(50);
c1.setNum(10);
c2.setNum(20);
c3.setNum(30);
c4.setNum(40);
c5.setNum(50);
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c1.start();
c2.start();
c3.start();
c4.start();
c5.start();
}
}
ReentrantLock需要注意try{}finally{lock.unlock();}
OVER