提供三種方法來解決消費者生產者問題
第一種:利用synchronized與wait、notify
public class ProConWN {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
ExecutorService service = Executors.newFixedThreadPool(15);
for (int i = 0; i < 5; i++) {
service.submit(new Productor(linkedList, 8));
}
for (int i = 0; i < 10; i++) {
service.submit(new Consumer(linkedList));
}
}
static class Productor implements Runnable {
private List<Integer> list;
private int maxLength;
public Productor(List<Integer> list, int maxLength) {
this.list = list;
this.maxLength = maxLength;
}
@Override
public void run() {
while (true) {
synchronized (list) {
try {
while (list.size() == maxLength) {
System.out.println("生產者" + Thread.currentThread().getName() + "list已達到最大容量,進行wait等待");
list.wait();
System.out.println("生產者" + Thread.currentThread().getName() + "退出wait");
}
Random random = new Random();
int i = random.nextInt();
System.out.println("生產者" + Thread.currentThread().getName() + "生產數據" + i);
list.add(i);
list.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
static class Consumer implements Runnable {
private List<Integer> list = null;
public Consumer(List list) {
this.list = list;
}
@Override
public void run() {
while (true) {
synchronized (list) {
try {
while (list.isEmpty()) {
System.out.println("消費者" + Thread.currentThread().getName() + "list爲空,進行wait等候");
list.wait();
System.out.println("消費者" + Thread.currentThread().getName() + "退出wait");
}
Integer element = list.remove(0);
System.out.println("消費者" + Thread.currentThread().getName() + "消費數據" + element);
list.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
第二種:利用lock鎖
public class ProConLock {
private static ReentrantLock lock = new ReentrantLock();
private static Condition full = lock.newCondition();
private static Condition empty = lock.newCondition();
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
ExecutorService service = Executors.newFixedThreadPool(15);
for (int i = 0; i < 5; i++) {
service.submit(new Productor(linkedList, 8, lock));
}
for (int i = 0; i < 10; i++) {
service.submit(new Consumer(linkedList, lock));
}
}
static class Productor implements Runnable {
private List<Integer> list;
private int maxLength;
private Lock lock;
public Productor(List<Integer> list, int maxLength, Lock lock) {
this.list = list;
this.maxLength = maxLength;
this.lock = lock;
}
@Override
public void run() {
while (true) {
lock.lock();
try {
while (list.size() == maxLength) {
System.out.println("生產者" + Thread.currentThread().getName() + "list達到最大容量,進行wait");
full.await();
System.out.println("生產者" + Thread.currentThread().getName() + "退出wait");
}
Random random = new Random();
int i = random.nextInt();
System.out.println("生產者" + Thread.currentThread().getName() + "生產數據" + i);
list.add(i);
empty.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
static class Consumer implements Runnable {
private List<Integer> list;
private Lock lock;
public Consumer(List<Integer> list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
while (true) {
lock.lock();
try {
while (list.isEmpty()) {
System.out.println("消費者" + Thread.currentThread().getName() + "list爲空,進行wait");
empty.await();
System.out.println("消費者" + Thread.currentThread().getName() + "退出wait");
}
Integer element = list.remove(0);
System.out.println("消費者" + Thread.currentThread().getName() + "消費數據" + element);
full.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
第三種:利用阻塞隊LinkedBlockingQueue
public class ProConBlocking {
private static LinkedBlockingQueue<Math> queue = new LinkedBlockingQueue<Math>();
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(15);
for (int i = 0; i < 5; i++) {
service.submit(new Productor(queue));
}
for (int i = 0; i < 10; i++) {
service.submit(new Consumer(queue));
}
}
static class Productor implements Runnable {
private BlockingQueue<Integer> queue;
public Productor(BlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while (true) {
Random random = new Random();
int i = random.nextInt();
System.out.println("生產者" + Thread.currentThread().getName() + "生產數據" + i);
queue.put(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class Consumer implements Runnable {
private BlockingQueue<Integer> queue;
public Consumer(BlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while (true) {
Integer element = queue.take();
System.out.println("消費者" + Thread.currentThread().getName() + "正在消費數據" + element);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}