生产者消费者模式的多种实现
1. synchronized方式
1.1 方法简介
- Object.wait() 使当前的线程进入到等待状态【进入到等待队列】
- Object.notifyAll() 唤醒等待中的全部线程
- Object.notify() 随机唤醒一个线程
1.2 代码
package thread.consumer;
import java.util.ArrayList;
import java.util.List;
public class Consumer extends Thread{
List<Object> container;
private int count;
public Consumer(String name, List<Object> container) {
super(name);
this.container = container;
}
@Override
public void run() {
while(true){
synchronized (container){
try{
if(container.isEmpty()){
container.wait();
}else{
container.remove(0);
this.count++;
System.out.print(getName() + "共消费:" + this.count);
System.out.println(" 当前剩余:" + this.container.size());
System.out.println();
container.notifyAll();
}
} catch (InterruptedException e){
e.printStackTrace();
}
}
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer extends Thread{
List<Object> container;
private int count;
public Producer(String name, List<Object> container) {
super(name);
this.container = container;
}
@Override
public void run() {
while(true){
synchronized (container){
try{
if(container.size() == 10){
container.wait();
}else{
container.add(new Object());
this.count++;
System.out.print(getName() + "共生产:" + this.count);
System.out.println(" 当前剩余:" + this.container.size());
System.out.println();
container.notifyAll();
}
} catch (InterruptedException e){
e.printStackTrace();
}
}
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Main{
public static void main(String[] args) {
List<Object> container = new ArrayList<>();
new Producer("生产者1", container).start();
new Producer("生产者2", container).start();
new Producer("生产者3", container).start();
new Producer("生产者4", container).start();
new Consumer("消费者1", container).start();
new Consumer("消费者2", container).start();
new Consumer("消费者3", container).start();
new Consumer("消费者4", container).start();
}
}
生产者1共生产:1 当前剩余:1
生产者4共生产:1 当前剩余:2
生产者2共生产:1 当前剩余:3
生产者3共生产:1 当前剩余:4
生产者2共生产:2 当前剩余:5
生产者4共生产:2 当前剩余:6
生产者1共生产:2 当前剩余:7
消费者1共消费:1 当前剩余:6
消费者2共消费:1 当前剩余:5
生产者3共生产:2 当前剩余:6
生产者4共生产:3 当前剩余:7
生产者1共生产:3 当前剩余:8
生产者2共生产:3 当前剩余:9
消费者4共消费:1 当前剩余:8
消费者3共消费:1 当前剩余:7
生产者3共生产:3 当前剩余:8
生产者2共生产:4 当前剩余:9
生产者1共生产:4 当前剩余:10
消费者4共消费:2 当前剩余:9
消费者1共消费:2 当前剩余:8
消费者2共消费:2 当前剩余:7
消费者3共消费:2 当前剩余:6
生产者1共生产:5 当前剩余:7
生产者2共生产:5 当前剩余:8
生产者4共生产:4 当前剩余:9
生产者3共生产:4 当前剩余:10
消费者3共消费:3 当前剩余:9
消费者1共消费:3 当前剩余:8
消费者4共消费:3 当前剩余:7
消费者2共消费:3 当前剩余:6
生产者3共生产:5 当前剩余:7
生产者2共生产:6 当前剩余:8
生产者4共生产:5 当前剩余:9
生产者1共生产:6 当前剩余:10
2. ReentrantLock方式
2.1 方法简介
2.2 代码
package thread.reentrantlock;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Consumer extends Thread {
List<Object> container;
private int count;
private Lock lock;
private Condition condition;
public Consumer(String name, List<Object> container, Lock lock, Condition condition) {
super(name);
this.container = container;
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
while (true) {
lock.lock();
try {
if (container.isEmpty()) {
condition.await();
} else {
container.remove(0);
this.count++;
System.out.print(getName() + "共消费:" + this.count);
System.out.println(" 当前剩余:" + this.container.size());
System.out.println();
condition.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer extends Thread {
List<Object> container;
private int count;
private Lock lock;
private Condition condition;
public Producer(String name, List<Object> container, Lock lock, Condition condition) {
super(name);
this.container = container;
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
while (true) {
lock.lock();
try {
if (container.size() == 10) {
condition.await();
} else {
container.add(new Object());
this.count++;
System.out.print(getName() + "共生产:" + this.count);
System.out.println(" 当前剩余:" + this.container.size());
System.out.println();
condition.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Main {
public static void main(String[] args) {
List<Object> container = new ArrayList<>();
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
new Producer("生产者1", container, lock, condition).start();
new Producer("生产者2", container, lock, condition).start();
new Producer("生产者3", container, lock, condition).start();
new Producer("生产者4", container, lock, condition).start();
new Consumer("消费者1", container, lock, condition).start();
new Consumer("消费者2", container, lock, condition).start();
new Consumer("消费者3", container, lock, condition).start();
new Consumer("消费者4", container, lock, condition).start();
}
}
生产者1共生产:1 当前剩余:1
生产者2共生产:1 当前剩余:2
生产者3共生产:1 当前剩余:3
生产者4共生产:1 当前剩余:4
生产者2共生产:2 当前剩余:5
生产者1共生产:2 当前剩余:6
生产者3共生产:2 当前剩余:7
消费者1共消费:1 当前剩余:6
消费者2共消费:1 当前剩余:5
生产者4共生产:2 当前剩余:6
生产者2共生产:3 当前剩余:7
消费者3共消费:1 当前剩余:6
消费者4共消费:1 当前剩余:5
生产者3共生产:3 当前剩余:6
生产者1共生产:3 当前剩余:7
生产者4共生产:3 当前剩余:8
生产者2共生产:4 当前剩余:9
生产者3共生产:4 当前剩余:10
3. 优化-使用多个Condition
package thread.reentrantlock;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Consumer extends Thread {
List<Object> container;
private int count;
private Lock lock;
private Condition consumer;
private Condition producer;
public Consumer(String name, List<Object> container, Lock lock, Condition consumer, Condition producer) {
super(name);
this.container = container;
this.lock = lock;
this.consumer = consumer;
this.producer = producer;
}
@Override
public void run() {
while (true) {
lock.lock();
try {
if (container.isEmpty()) {
consumer.await();
} else {
container.remove(0);
this.count++;
System.out.print(getName() + "共消费:" + this.count);
System.out.println(" 当前剩余:" + this.container.size());
System.out.println();
producer.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer extends Thread {
List<Object> container;
private int count;
private Lock lock;
private Condition consumer;
private Condition producer;
public Producer(String name, List<Object> container, Lock lock, Condition consumer, Condition producer) {
super(name);
this.container = container;
this.lock = lock;
this.consumer = consumer;
this.producer = producer;
}
@Override
public void run() {
while (true) {
lock.lock();
try {
if (container.size() == 10) {
producer.await();
} else {
container.add(new Object());
this.count++;
System.out.print(getName() + "共生产:" + this.count);
System.out.println(" 当前剩余:" + this.container.size());
System.out.println();
consumer.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Main {
public static void main(String[] args) {
List<Object> container = new ArrayList<>();
Lock lock = new ReentrantLock();
Condition consumer = lock.newCondition();
Condition producer = lock.newCondition();
new Producer("生产者1", container, lock, consumer, producer).start();
new Producer("生产者2", container, lock, consumer, producer).start();
new Producer("生产者3", container, lock, consumer, producer).start();
new Producer("生产者4", container, lock, consumer, producer).start();
new Consumer("消费者1", container, lock, consumer, producer).start();
new Consumer("消费者2", container, lock, consumer, producer).start();
new Consumer("消费者3", container, lock, consumer, producer).start();
new Consumer("消费者4", container, lock, consumer, producer).start();
}
}