Java线程之间的通信分为共享内存,消息机制,管道(PipedInputStream / PipedOutputStream)大概三种模式。生产者消费者模式是多线程问题当中一个非常经典的问题,从我们大学的《操作系统》的课本当中的位置和课时,我们便可以知道这个思想的重要性,而且在实际生产当中生产者消费者模式为我们解决了大量的并发问题。一个简单的例子,并发编程大师Doug Lea的阻塞队列便是生产者消费者模式的典型实现,这里主要使用记录一下生产者消费者模式的集中写法,并探讨一下,这集中写法所产生的不同。
1、wait() / notify()模式
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by Yang on 2015/12/14.
*/
public class MainTest01 {
// 最大容量
private static int MAX_SIZE = 100;
// 共享的仓库
private static LinkedList<String> list = new LinkedList<String>();
private static class Productor implements Runnable {
private int num;
public Productor(int num) {
this.num = num;
}
public void product() throws InterruptedException {
synchronized (list) {
while ((list.size() + num > MAX_SIZE)) {
System.out.println("仓库现有:" + list.size() + ";要生产:" + num + ";大于仓库容量:" + MAX_SIZE + ";暂停生产!");
list.wait();
}
// 业务逻辑
for (int i = 0; i < num; i++) {
list.add("Product " + i);
}
System.out.println("生产了:" + num + ";仓库现有:" + list.size());
//
list.notifyAll();
}
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
try {
product();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class Consumer implements Runnable {
private int num;
public Consumer(int num) {
this.num = num;
}
public void consume() throws InterruptedException {
// 进入锁
synchronized (list) {
while (list.size() < num) {
System.out.println("仓库现有:" + list.size() + ";要消费:" + num + ";暂停消费!");
list.wait();
}
// 业务逻辑
for (int i = 0; i < num; i++) {
list.remove();
}
System.out.println("消费了:" + num + ";仓库现有:" + list.size());
//
list.notifyAll();
}
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
try {
consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new Productor(10));
executorService.execute(new Consumer(10));
executorService.execute(new Productor(10));
executorService.execute(new Consumer(50));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.shutdown();
}
}
2、await() / signal()模式
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by Yang on 2015/12/14.
*/
public class MainTest01 {
// 最大容量
private static int MAX_SIZE = 100;
// 共享的仓库
private static LinkedList<String> list = new LinkedList<String>();
private static final Lock lock = new ReentrantLock();
private static final Condition notFull = lock.newCondition();
private static final Condition notEmpty = lock.newCondition();
private static class Productor implements Runnable {
private int num;
public Productor(int num) {
this.num = num;
}
public void product() throws InterruptedException {
lock.lock();
try {
while ((list.size() + num > MAX_SIZE)) {
System.out.println("仓库现有:" + list.size() + ";要生产:" + num + ";大于仓库容量:" + MAX_SIZE + ";暂停生产!");
notFull.await();
}
// 业务逻辑
for (int i = 0; i < num; i++) {
list.add("Product " + i);
}
System.out.println("生产了:" + num + ";仓库现有:" + list.size());
//
notEmpty.signalAll();
} finally {
lock.unlock();
}
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
try {
product();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class Consumer implements Runnable {
private int num;
public Consumer(int num) {
this.num = num;
}
public void consume() throws InterruptedException {
// 进入锁
lock.lock();
try {
while (list.size() < num) {
System.out.println("仓库现有:" + list.size() + ";要消费:" + num + ";暂停消费!");
notEmpty.await();
}
// 业务逻辑
for (int i = 0; i < num; i++) {
list.remove();
}
System.out.println("消费了:" + num + ";仓库现有:" + list.size());
//
notFull.signalAll();
} finally {
lock.unlock();
}
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
try {
consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new Productor(10));
executorService.execute(new Consumer(10));
executorService.execute(new Productor(10));
executorService.execute(new Consumer(50));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.shutdown();
}
}
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by Yang on 2015/12/14.
*/
public class MainTest02 {
// 最大容量
private static int MAX_SIZE = 100;
// 共享的仓库
private static LinkedList<String> list = new LinkedList<String>();
private static final Lock lock = new ReentrantLock();
private static final Condition condition = lock.newCondition();
private static class Productor implements Runnable {
private int num;
public Productor(int num) {
this.num = num;
}
public void product() throws InterruptedException {
lock.lock();
try {
while ((list.size() + num > MAX_SIZE)) {
System.out.println("仓库现有:" + list.size() + ";要生产:" + num + ";大于仓库容量:" + MAX_SIZE + ";暂停生产!");
condition.await();
}
// 业务逻辑
for (int i = 0; i < num; i++) {
list.add("Product " + i);
}
System.out.println("生产了:" + num + ";仓库现有:" + list.size());
//
condition.signalAll();
} finally {
lock.unlock();
}
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
try {
product();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class Consumer implements Runnable {
private int num;
public Consumer(int num) {
this.num = num;
}
public void consume() throws InterruptedException {
// 进入锁
lock.lock();
try {
while (list.size() < num) {
System.out.println("仓库现有:" + list.size() + ";要消费:" + num + ";暂停消费!");
condition.await();
}
// 业务逻辑
for (int i = 0; i < num; i++) {
list.remove();
}
System.out.println("消费了:" + num + ";仓库现有:" + list.size());
//
condition.signalAll();
} finally {
lock.unlock();
}
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
try {
consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new Productor(10));
executorService.execute(new Consumer(10));
executorService.execute(new Productor(10));
executorService.execute(new Consumer(50));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.shutdown();
}
}
3、阻塞队列模式
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Created by Yang on 2015/12/14.
*/
public class MainTest01 {
// 最大容量
private static int MAX_SIZE = 100;
// 共享的仓库
private static LinkedBlockingQueue<String> list = new LinkedBlockingQueue<String>(MAX_SIZE);
private static class Productor implements Runnable {
private int num;
public Productor(int num) {
this.num = num;
}
public void product() throws InterruptedException {
if ((list.size() + num > MAX_SIZE)) {
System.out.println("仓库现有:" + list.size() + ";要生产:" + num + ";大于仓库容量:" + MAX_SIZE + ";暂停生产!");
}
// 业务逻辑
for (int i = 0; i < num; i++) {
list.put("Product " + i);
}
System.out.println("生产了:" + num + ";仓库现有:" + list.size());
//
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
try {
product();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static class Consumer implements Runnable {
private int num;
public Consumer(int num) {
this.num = num;
}
public void consume() throws InterruptedException {
if (list.size() < num) {
System.out.println("仓库现有:" + list.size() + ";要消费:" + num + ";暂停消费!");
}
// 业务逻辑
for (int i = 0; i < num; i++) {
list.take();
}
System.out.println("消费了:" + num + ";仓库现有:" + list.size());
//
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public void run() {
try {
consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.execute(new Productor(10));
executorService.execute(new Consumer(10));
executorService.execute(new Productor(10));
executorService.execute(new Consumer(50));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.execute(new Productor(10));
executorService.shutdown();
}
}