它可以用来解决:
- 1.生产与消费速度不匹配的问题;
- 2.软件开发过程中解耦。
| 阻塞情况 | 唤醒情况 |
|---|---|
| 1.队列已满,阻塞生产者 | 1.队列不满,唤醒生产者 |
| 2.队列已空,阻塞消费者 | 2.队列不空,唤醒消费者 |
注意:阻塞时只能用wait()方法,不能用sleep()方法,因为此时不释放锁。假设队列为空,那么消费者sleep,此时消费者不释放锁,那么生产者拿不到锁就不能生产,队列一直是空,则消费者一直sleep().形成死锁。
1.阻塞队列import java.util.*;
public class BlockQueue {
1.维护的队列
private Queue queue;
2.队列最大容量
private int capacity;
public BlockQueue(int capacity) {
this.queue = new linkedList();
this.capacity = capacity;
}
生产者方法 加sychronized锁,是为了防止多生产者造成的线程安全
public synchronized void produce(int i) throws InterruptedException{
1.队列满则 生产者阻塞
while (queue.size()==capacity){
wait();
}
queue.add(i);
2.已经生产, 唤醒消费者
notifyAll();
}
消费者方法 加sychronized锁,是为了防止多消费者造成的线程安全
public synchronized int consume() throws InterruptedException{
1.队列为空 消费者阻塞
while (queue.size()==0){
wait();
}
Integer res = (Integer) queue.poll();
2.队列不满,唤醒生产者
notifyAll();
return res;
}
}
2.生产者
public class Producer implements Runnable{
private BlockQueue blockQueue;
public Producer(BlockQueue blockQueue) {
this.blockQueue = blockQueue;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
blockQueue.produce(i);
System.out.println("生产者生产:"+i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3.消费者
public class Consumer implements Runnable {
private BlockQueue blockQueue;
public Consumer(BlockQueue blockQueue) {
this.blockQueue = blockQueue;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
int consume = blockQueue.consume();
System.out.println("消费者线程:"+ Thread.currentThread().getName() +":消费:"+consume);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4.测试
public class Main {
public static void main(String[] args) {
BlockQueue blockQueue = new BlockQueue(20);
new Thread(new Producer(blockQueue),"producer").start();
new Thread(new Consumer(blockQueue),"consumer").start();
}
}



