Java实现生产者消费者模型
信号量方式
import java.util.ArrayDeque;
import java.util.concurrent.Semaphore;
public class ProducerAndCustomer {
public static void main(String[] args) {
Manager manager = new Manager();
for (int i = 0; i < 3; i++) {
Thread producer = new Thread(() -> {
while (true) {
manager.put(new Object());
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producer.setName("生产者线程" + i);
producer.start();
Thread customer = new Thread(() -> {
while (true) {
manager.take();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
customer.setName("消费者线程" + i);
customer.start();
}
}
static class Manager {
Semaphore mutex = new Semaphore(1);
Semaphore empty = new Semaphore(10);
Semaphore full = new Semaphore(0);
ArrayDeque<Object> items = new ArrayDeque<>();
static int putNum = 0;
static int getNum = 0;
public void put(Object item) {
try {
empty.acquire();
mutex.acquire();
items.addLast(item);
putNum++;
System.out.println(Thread.currentThread().getName() + "正在生产第" + putNum + "个产品");
full.release();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mutex.release();
}
}
public Object take() {
try {
full.acquire();
mutex.acquire();
Object item = items.removeFirst();
getNum++;
System.out.println(Thread.currentThread().getName() + "正在消费第" + getNum + "个产品");
empty.release();
return item;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mutex.release();
}
return null;
}
}
}
synchronized方式
public class Demo1 {
static Object lock = new Object();
static int empty = 10;
static int full = 0;
static int putNum = 0;
static int getNum = 0;
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread producer = new Thread(new Producer(lock));
producer.setName("生产者线程" + i);
producer.start();
Thread customer = new Thread(new Customer(lock));
customer.setName("消费者线程" + i);
customer.start();
}
}
static class Producer implements Runnable {
final Object lock;
public Producer(Object lock) {
this.lock = lock;
}
@Override
public void run() {
while (true) {
synchronized (lock) {
try {
while (empty <= 0) {
lock.wait();
}
putNum++;
empty--;
full++;
System.out.println(Thread.currentThread().getName() + "正在生产第" + putNum + "个产品");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.notifyAll();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
static class Customer implements Runnable {
final Object lock;
public Customer(Object lock) {
this.lock = lock;
}
@Override
public void run() {
while (true) {
synchronized (lock) {
try {
while (full <= 0) {
lock.wait();
}
getNum++;
full--;
empty++;
System.out.println(Thread.currentThread().getName() + "正在消费第" + getNum + "个产品");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.notifyAll();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
Lock方式
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Demo2 {
static int empty = 10;
static int full = 0;
static int putNum = 0;
static int getNum = 0;
static ReentrantLock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread producer = new Thread(new Producer());
producer.setName("生产者线程" + i);
producer.start();
Thread customer = new Thread(new Customer());
customer.setName("消费者线程" + i);
customer.start();
}
}
static class Producer implements Runnable {
@Override
public void run() {
while (true) {
try {
lock.lock();
while (empty <= 0) {
condition.await();
}
full++;
empty--;
putNum++;
System.out.println(Thread.currentThread().getName() + "正在生产第" + putNum + "个产品");
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
static class Customer implements Runnable {
@Override
public void run() {
while (true) {
try {
lock.lock();
while (full <= 0) {
condition.await();
}
full--;
empty++;
getNum++;
System.out.println(Thread.currentThread().getName() + "正在消费第" + getNum + "个产品");
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}