1.生产者消费者模式
生产者消费者模式是一个十分经典的多线程协作的模式,主要用于解决多线程间的同步问题。它描述了两个类之间的协作:生产者和消费者。生产者负责生成数据(或称为“产品”),而消费者负责消费这些数据。这种模式通常用于解决多线程间共享数据的问题
2.代码实现生产者消费者模式
(1)同步机制
public class Resource {
public static Integer tag = 0; // 控制哪个线程运行
public static Integer count = 10; // 模拟某种资源
public final static Object lock = new Object(); // 锁对象
}
(2)生产者
public class Producer extends Thread {
@Override
public void run() {
while(true) {
synchronized (Resource.lock) {
if (Resource.count == 0) {
break;
} else {
if (Resource.tag == 1) {
try {
Resource.lock.wait();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
} else {
System.out.println("生产者生产一个产品");
Resource.tag = 1;
Resource.lock.notifyAll();
}
}
}
}
}
}
(3)消费者
public class Consumer extends Thread {
@Override
public void run() {
while(true) {
synchronized (Resource.lock) {
if (Resource.count == 0) {
break;
} else {
if (Resource.tag == 0) {
try {
Resource.lock.wait();// 当前线程跟锁进行绑定
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
} else {
Resource.count--;
System.out.println("消费者消费了一个资源,还剩"+ Resource.count+"个资源");
Resource.lock.notifyAll();
Resource.tag = 0;
}
}
}
}
}
}
3.利用阻塞队列实现生产者消费者模式
核心:生产者和消费者共用一个阻塞队列
(1)生产者
public class Producer extends Thread {
ArrayBlockingQueue<String> queue;
public Producer(ArrayBlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
try {
queue.put("数据"); //生产者生产了一个数据
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
(2)消费者
public class Consumer extends Thread {
ArrayBlockingQueue<String> queue;
public Consumer(ArrayBlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true) {
try {
String data = queue.take();// 消费者消费了一个数据
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
(3)共用一个阻塞队列
public class Demo {
public static void main(String[] args) {
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
Producer producer = new Producer(queue);
producer.setName("生产者");
Consumer consumer = new Consumer(queue);
consumer.setName("消费者");
producer.start();
consumer.start();
}