说明:参考《Java多线程核心技术》
5、生产者/消费者模式
1、一个生产者一个消费者
public class MyStack {
private List list = new ArrayList();
synchronized public void push() { // push to stack
try {
if (list.size() == 1) { // while
this.wait();
}
list.add("anyString = " + Math.random());
this.notify();
System.out.println("push size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public String pop() { // pop from stack
String returnValue = "";
try {
if (list.size() == 0) { // while
System.out.println("pop " + Thread.currentThread().getName() + " is waiting");
this.wait();
}
returnValue = "" + list.get(0);
list.remove(0);
this.notify();
System.out.println("pop size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
}
public class Product {
private MyStack myStack;
public Product(MyStack myStack) {
this.myStack = myStack;
}
public void pushService() {
myStack.push();
}
}
public class Consume {
private MyStack myStack;
public Consume(MyStack myStack) {
super();
this.myStack = myStack;
}
public void popService() {
System.out.println("pop = " + myStack.pop());
}
}
public class ProductThread extends Thread{
private Product product;
public ProductThread(Product product) {
this.product = product;
}
@Override
public void run() {
while (true) {
product.pushService();
}
}
}
public class ConsumeThread extends Thread{
private Consume consume;
public ConsumeThread(Consume consume) {
super();
this.consume = consume;
}
@Override
public void run() {
while (true) {
consume.popService();
}
}
}
public class OneProductTest {
public static void main(String[] args) {
MyStack myStack = new MyStack();
Product product = new Product(myStack);
Consume consume = new Consume(myStack);
ProductThread productThread = new ProductThread(product);
ConsumeThread consumeThread = new ConsumeThread(consume);
productThread.start();
consumeThread.start();
}
}
/**
push size = 1
pop = anyString = 0.413003818915496
pop size = 0
push size = 1
pop = anyString = 0.24254707748827975
pop size = 0
...
*/
通过生产者和消费者,容器的size()不会大于1。
2、一个生产者多个消费者
public class MyStack {
private List list = new ArrayList();
synchronized public void push() { // push to stack
try {
while (list.size() == 1) {
this.wait();
}
list.add("anyString = " + Math.random());
this.notifyAll();
System.out.println("push size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public String pop() { // pop from stack
String returnValue = "";
try {
while (list.size() == 0) {
System.out.println("pop " + Thread.currentThread().getName() + " is waiting");
this.wait();
}
returnValue = "" + list.get(0);
list.remove(0);
this.notifyAll();
System.out.println("pop size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
}
public class Product {
private MyStack myStack;
public Product(MyStack myStack) {
this.myStack = myStack;
}
public void pushService() {
myStack.push();
}
}
public class Consume {
private MyStack myStack;
public Consume(MyStack myStack) {
super();
this.myStack = myStack;
}
public void popService() {
System.out.println("pop = " + myStack.pop());
}
}
public class ProductThread extends Thread{
private Product product;
public ProductThread(Product product) {
this.product = product;
}
@Override
public void run() {
while (true) {
product.pushService();
}
}
}
public class ConsumeThread extends Thread{
private Consume consume;
public ConsumeThread(Consume consume) {
super();
this.consume = consume;
}
@Override
public void run() {
while (true) {
consume.popService();
}
}
}
public class MultiConsumeTest {
public static void main(String[] args) {
MyStack myStack = new MyStack();
Product product = new Product(myStack);
Consume consume= new Consume(myStack);
Consume consume1 = new Consume(myStack);
Consume consume2 = new Consume(myStack);
ProductThread productThread = new ProductThread(product);
ConsumeThread consumeThread = new ConsumeThread(consume);
ConsumeThread consumeThread1 = new ConsumeThread(consume1);
ConsumeThread consumeThread2 = new ConsumeThread(consume2);
productThread.start();
consumeThread.start();
consumeThread1.start();
consumeThread2.start();
}
}
/**
push size = 1
pop size = 0
pop = anyString = 0.8524272104911793
pop Thread-2 is waiting
push size = 1
pop size = 0
pop = anyString = 0.27216364463077425
pop Thread-3 is waiting
pop Thread-1 is waiting
push size = 1
pop size = 0
pop = anyString = 0.36276482939085863
push size = 1
...
*/
注意点: 使用while;使用notifyAll();
3、多个生产者一个消费者
public class MyStack {
private List list = new ArrayList();
synchronized public void push() { // push to stack
try {
while (list.size() == 1) {
this.wait();
}
list.add("anyString = " + Math.random());
this.notifyAll();
System.out.println("push size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public String pop() { // pop from stack
String returnValue = "";
try {
while (list.size() == 0) {
System.out.println("pop " + Thread.currentThread().getName() + " is waiting");
this.wait();
}
returnValue = "" + list.get(0);
list.remove(0);
this.notifyAll();
System.out.println("pop size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
}
public class Product {
private MyStack myStack;
public Product(MyStack myStack) {
this.myStack = myStack;
}
public void pushService() {
myStack.push();
}
}
public class Consume {
private MyStack myStack;
public Consume(MyStack myStack) {
super();
this.myStack = myStack;
}
public void popService() {
System.out.println("pop = " + myStack.pop());
}
}
public class ProductThread extends Thread{
private Product product;
public ProductThread(Product product) {
this.product = product;
}
@Override
public void run() {
while (true) {
product.pushService();
}
}
}
public class ConsumeThread extends Thread{
private Consume consume;
public ConsumeThread(Consume consume) {
super();
this.consume = consume;
}
@Override
public void run() {
while (true) {
consume.popService();
}
}
}
public class MultiConsumeTest {
public static void main(String[] args) {
MyStack myStack = new MyStack();
Product product = new Product(myStack);
Consume consume= new Consume(myStack);
Consume consume1 = new Consume(myStack);
Consume consume2 = new Consume(myStack);
ProductThread productThread = new ProductThread(product);
ConsumeThread consumeThread = new ConsumeThread(consume);
ConsumeThread consumeThread1 = new ConsumeThread(consume1);
ConsumeThread consumeThread2 = new ConsumeThread(consume2);
productThread.start();
consumeThread.start();
consumeThread1.start();
consumeThread2.start();
}
}
/**
push size = 1
pop size = 0
pop = anyString = 0.8524272104911793
pop Thread-2 is waiting
push size = 1
pop size = 0
pop = anyString = 0.27216364463077425
pop Thread-3 is waiting
pop Thread-1 is waiting
push size = 1
pop size = 0
pop = anyString = 0.36276482939085863
push size = 1
...
*/
注意点: 使用while;使用notifyAll();
4、多个生产者一个消费者
public class MyStack {
private List list = new ArrayList();
synchronized public void push() { // push to stack
try {
while (list.size() == 1) {
this.wait();
}
list.add("anyString = " + Math.random());
this.notifyAll();
System.out.println("push size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public String pop() { // pop from stack
String returnValue = "";
try {
while (list.size() == 0) {
System.out.println("pop " + Thread.currentThread().getName() + " is waiting");
this.wait();
}
returnValue = "" + list.get(0);
list.remove(0);
this.notifyAll();
System.out.println("pop size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
}
public class Product {
private MyStack myStack;
public Product(MyStack myStack) {
this.myStack = myStack;
}
public void pushService() {
myStack.push();
}
}
public class Consume {
private MyStack myStack;
public Consume(MyStack myStack) {
super();
this.myStack = myStack;
}
public void popService() {
System.out.println("pop = " + myStack.pop());
}
}
public class ProductThread extends Thread{
private Product product;
public ProductThread(Product product) {
this.product = product;
}
@Override
public void run() {
while (true) {
product.pushService();
}
}
}
public class ConsumeThread extends Thread{
private Consume consume;
public ConsumeThread(Consume consume) {
super();
this.consume = consume;
}
@Override
public void run() {
while (true) {
consume.popService();
}
}
}
public class MultiProductTest {
public static void main(String[] args) {
MyStack myStack = new MyStack();
Product product = new Product(myStack);
Product product1 = new Product(myStack);
Product product2 = new Product(myStack);
ProductThread productThread = new ProductThread(product);
ProductThread productThread1 = new ProductThread(product1);
ProductThread productThread2 = new ProductThread(product2);
productThread.start();
productThread1.start();
productThread2.start();
Consume consume = new Consume(myStack);
ConsumeThread consumeThread = new ConsumeThread(consume);
consumeThread.start();
}
}
/**
push size = 1
pop size = 0
pop = anyString = 0.7074313942678033
pop Thread-3 is waiting
push size = 1
pop size = 0
pop = anyString = 0.9030921643856575
pop Thread-3 is waiting
push size = 1
pop size = 0
pop = anyString = 0.051652492487380686
pop Thread-3 is waiting
push size = 1
pop size = 0
pop = anyString = 0.9269650225595099
pop Thread-3 is waiting
...
*/
5、多个生产者对多个消费者
public class MyStack {
private List list = new ArrayList();
synchronized public void push() { // push to stack
try {
while (list.size() == 1) {
this.wait();
}
list.add("anyString = " + Math.random());
this.notifyAll();
System.out.println("push size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public String pop() { // pop from stack
String returnValue = "";
try {
while (list.size() == 0) {
System.out.println("pop " + Thread.currentThread().getName() + " is waiting");
this.wait();
}
returnValue = "" + list.get(0);
list.remove(0);
this.notifyAll();
System.out.println("pop size = " + list.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
}
public class Product {
private MyStack myStack;
public Product(MyStack myStack) {
this.myStack = myStack;
}
public void pushService() {
myStack.push();
}
}
public class Consume {
private MyStack myStack;
public Consume(MyStack myStack) {
super();
this.myStack = myStack;
}
public void popService() {
System.out.println("pop = " + myStack.pop());
}
}
public class ProductThread extends Thread{
private Product product;
public ProductThread(Product product) {
this.product = product;
}
@Override
public void run() {
while (true) {
product.pushService();
}
}
}
public class ConsumeThread extends Thread{
private Consume consume;
public ConsumeThread(Consume consume) {
super();
this.consume = consume;
}
@Override
public void run() {
while (true) {
consume.popService();
}
}
}
public class MultiConsumeTest {
public static void main(String[] args) {
MyStack myStack = new MyStack();
Product product = new Product(myStack);
Product product1 = new Product(myStack);
Product product2 = new Product(myStack);
Consume consume= new Consume(myStack);
Consume consume1 = new Consume(myStack);
Consume consume2 = new Consume(myStack);
ProductThread productThread = new ProductThread(product);
ProductThread productThread1 = new ProductThread(product1);
ProductThread productThread2 = new ProductThread(product2);
ConsumeThread consumeThread = new ConsumeThread(consume);
ConsumeThread consumeThread1 = new ConsumeThread(consume1);
ConsumeThread consumeThread2 = new ConsumeThread(consume2);
productThread.start();
productThread1.start();
productThread2.start();
consumeThread.start();
consumeThread1.start();
consumeThread2.start();
}
}
/**
push size = 1
pop size = 0
pop = anyString = 0.877645574289827
pop Thread-5 is waiting
push size = 1
pop size = 0
pop = anyString = 0.4771502604337374
push size = 1
pop size = 0
push size = 1
pop = anyString = 0.6845739056478685
pop size = 0
pop = anyString = 0.5083075161836528
pop Thread-3 is waiting
...
*/