多线程案例1
队列为满 消费者堵塞
队列为空 生产者堵塞
1.java中的阻塞式队列
import java.util.concurrent.BlockingQueue; //泛型接口
private static BlockingQueue<String> queue1 = new PriorityBlockingQueue<>();
//1.堆(优先级队列)
private static BlockingQueue<String> queue2 = new LinkedBlockingQueue<>();
//2.链表
private static BlockingQueue<String> queue3 = new ArrayBlockingQueue<>(10);
//3.循环队列 最大容量10
2.生产者消费者模式
生产者消费者模式:通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。
模拟测试一
条件:将阻塞队列容量设置为1,一个生产者,一个消费者。
结果:不会阻塞。
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class UseBlockingQueue {
private static BlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
private static class Producer extends Thread {
@Override
public void run() {
Random random = new Random(10_000_000);
while (true) {
try {
int message = random.nextInt(100);
queue.put(String.valueOf(message));
//只有 put 和 take 有阻塞效果
System.out.println("放入消息: " + message);
Thread.sleep(random.nextInt(3) * 100);//1ms/2ms/3ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static class Customer extends Thread {
@Override
public void run() {
Random random = new Random(10_000_000);
while (true) {
try {
String message = queue.take();
System.out.println("收到消息: " + message);
Thread.sleep(random.nextInt(3) * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread producer = new Producer();//生产者
Thread customer = new Customer();//消费者
producer.start();
customer.start();
}
}
模拟测试二
条件:一个生产者,一个消费者,数组容量一。
结果:不会阻塞。
import java.util.Random;
public class MyQueue {
private int[] array = new int[1];
private int front = 0;
private int rear = 0;
private int size = 0;
public synchronized void put(int message) throws InterruptedException {
while (size == array.length) {
wait();
}
array[rear] = message;
rear = (rear + 1) % array.length;
size++;
notifyAll();
}
public synchronized int take() throws InterruptedException {
while (size == 0) {
wait();
}
int message = array[front];
front = (front + 1) % array.length;
size--;
notifyAll();
return message;
}
private static final MyQueue queue = new MyQueue();
private static class Producer extends Thread {
@Override
public void run() {
Random random = new Random();
while (true) {
try {
queue.put(random.nextInt(100));
System.out.println("发送消息:"+message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static class Customer extends Thread {
@Override
public void run() {
while (true) {
try {
queue.take();
System.out.println("接收消息:"+message);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread p1 = new Producer();
Thread c1 = new Customer();
p1.start();
c1.start();
}
}
模拟测试三
public class MyQueue2 {
private int[] array = new int[10];
private volatile int size = 0;
private int front = 0;
private int rear = 0;
private Object full = new Object();
private Object empty = new Object();
public void put(int message) throws InterruptedException {
do {
while (size == array.length) {
synchronized (full) {
full.wait();
}
}
// 这里保证,size 一定是 < array.length 的
synchronized (this) { // 持续时间很久
if (size == array.length) {
continue;
}
array[rear] = message;
rear = (rear + 1) % array.length;
size++;
}
synchronized (empty) {
empty.notify();
}
return;
} while (true);
}
public synchronized int take() throws InterruptedException {
do {
while (size == 0) {
synchronized (empty) {
empty.wait();
}
}
int message;
synchronized (this) { // 这句代码可能会执行很长时间
if (size == 0) {
continue;
}
message = array[front];
front = (front + 1) % array.length;
size--;
}
synchronized (full) {
full.notify();
}
return message;
} while (true);
}
}