简单的生产者和消费者实现
1.main 方法
public static void main(String[] args) {
Desk desk = new Desk();
for (int i=0; i<4; i++) {
Consumer consumer = new Consumer(desk);
for (int j=0; j<10; j++) {
Thread thread1 = new Thread(consumer::consume);
thread1.start();
}
}
for (int i=0; i<4; i++) {
Producer producer = new Producer(desk);
for (int j=0; j<10; j++) {
Thread thread = new Thread(producer::produce);
thread.start();
}
}
}
2.生产者
import java.util.Random;
public class Producer {
private final Desk desk;
public Producer(Desk desk) {
this.desk = desk;
}
public void produce() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Random random = new Random();
int num = random.nextInt(1000);
desk.add(String.valueOf(num));
}
}
3.消费者
public class Consumer {
private final Desk desk;
public Consumer(Desk desk) {
this.desk = desk;
}
public void consume() {
String num = desk.delete();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
4.通道
import java.util.LinkedList;
import java.util.Queue;
public class Desk {
private final Queue<String> queue;
public Desk() {
this.queue = new LinkedList<>();
}
public synchronized void add(String num) {
while (queue.size() > 30) {
try {
this.wait(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.add(num);
System.out.println(Thread.currentThread().getName() + " 生产: " + num);
}
public synchronized String delete() {
while (null == queue.peek()) {
try {
this.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String num = queue.poll();
System.out.println(Thread.currentThread().getName() + " 消费: " + num);
return num;
}
}
说明
- 引入通道的原因是, 如果只有生产者, 那么无法保证他们生产出来的蛋糕一个不少的放进了集合里, 因为每个生产者都是一个实例对象, 而锁只能锁各自的实例对象.
- 引入了第三者通道, 就可以把锁设置为第三者的实例对象, 这样既保证了生产数量的准确, 也简化了生产者的代码.
- wait() 方法的执行必须先获得锁, 所以需要使用 synchronized 关键字