1 一个生产者一个消费者
生产者和消费者同步获取存放产品的队列
生产者在生产后通知消费者,在队列满时等待消费者取出
消费者在取出后通知生产者,在队列为空时等待生产者放入
- 场景类
import java.util.LinkedList;
import java.util.Queue;
public class Client {
public static void main(String[] args) throws InterruptedException {
Queue<String> queue = new LinkedList<>();
Producer p = new Producer(queue);
Customer c = new Customer(queue);
p.start();
c.start();
}
}
- 生产者
package t11;
import java.util.Queue;
public class Producer extends Thread {
private final Queue<String> queue;
public Producer(Queue<String> queue) {
this.queue = queue;
}
@Override
public void run(){
while (true) {
synchronized (queue) {
if (queue.size() > 4) {
System.out.println("队列已满,等待C");
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.add("sss");
System.out.println("P放入队列,队列大小:" + queue.size());
queue.notify();
}
try {
int a = (int) (Math.random() * 100);
Thread.sleep(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- 消费者
package t11;
import java.util.LinkedList;
import java.util.Queue;
public class Customer extends Thread {
private final Queue<String> queue;
public Customer(Queue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
synchronized (queue) {
if (queue.isEmpty()) {
System.out.println("队列为空,等待P");
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.poll();
System.out.println("C取出队列,队列大小:" + queue.size());
queue.notify();
}
try {
int a = (int) (Math.random() * 100);
Thread.sleep(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2 多个生产者多个消费者
继续使用上面的代码,会出现“假死”的情况。
三个生产者,一个消费者;由于生产者生产完后没有激活消费者,而是激活另外一个消费者,导致所有线程都堵塞了。
P0 队列已满等待
P2 队列已满等待
C0 C取出队列,队列大小:0
C0 队列为空等待
P1 P放入队列,队列大小:1
P0 队列已满等待
P1 队列已满等待
P2 队列已满等待
将notify()方法改为notifyAll()方法,让生产者生产完后激活所有线程(队列满时,其他生产者在执行过程中会自动堵塞,从而消费者开始运行)。
场景类:
public class Client {
public static void main(String[] args) throws InterruptedException {
Queue<String> queue = new LinkedList<>();
Producer[] producers = new Producer[3];
Customer[] customers = new Customer[1];
for (int i = 0; i < producers.length; i++) {
producers[i] = new Producer(queue);
producers[i].setName("P" + i);
}
for (int i = 0; i < producers.length; i++) {
producers[i].start();
}
for (int i = 0; i < customers.length; i++) {
customers[i] = new Customer(queue);
customers[i].setName("C" + i);
}
for (int i = 0; i < customers.length; i++) {
customers[i].start();
}
}
}
生产者:
public class Producer extends Thread {
private final Queue<String> queue;
private static final int capactiy = 1;
public Producer(Queue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
synchronized (queue) {
try {
if (queue.size() >= capactiy) {
System.out.println(Thread.currentThread().getName() + " 队列已满等待");
queue.wait();
} else {
queue.add("sss");
System.out.println(Thread.currentThread().getName()
+ " P放入队列,队列大小:" + queue.size());
queue.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
int a = (int) (Math.random() * 100);
Thread.sleep(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
消费者:
public class Customer extends Thread {
private final Queue<String> queue;
public Customer(Queue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
synchronized (queue) {
try {
if (queue.isEmpty()) {
System.out.println(Thread.currentThread().getName() + " 队列为空等待");
queue.wait();
} else {
if (queue.poll() == null) {
System.out.println("对列为空,无法出队");
System.exit(1);
} else {
System.out.println(Thread.currentThread().getName()
+ " C取出队列,队列大小:" + queue.size());
queue.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
int a = (int) (Math.random() * 100);
Thread.sleep(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}