经典的多线程问题
生产者消费者模型:
1. 商品
2. 仓库
3. 生产者
4. 消费者
整个过程大致为:生产者将生产的商品放到仓库存储,消费者将仓库中的商品取出;其中,当库存为零时,消费者会通知生产进行生产;当库存已满时,生产者通知消费者进行消费.
代码
Product.java
package com.pc.product;
import java.io.Serializable;
public class Product implements Serializable {
private static int counter = 0;
private int no = ++counter;
private String name;
public Product(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Product [no=" + no + ", name=" + name + "]";
}
}
Storage.java
package com.pc.storage;
import java.util.ArrayList;
import java.util.List;
import com.pc.product.Product;
public class Storage<E extends Product> {
private int capacity = 10;
private List<E> productsList;
public Storage() {
productsList = new ArrayList<E>(capacity);
}
public Storage(int capacity) {
if (capacity <= 0) {
this.capacity = capacity;
}
productsList = new ArrayList<E>(capacity);
}
public void put(E e) {
synchronized (productsList) {
if (productsList.size() == capacity) {
try {
productsList.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} else {
productsList.add(e);
productsList.notifyAll();
}
}
}
public E take() {
synchronized (productsList) {
if (productsList.size() == 0) {
try {
productsList.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} else {
productsList.notifyAll();
return productsList.remove(0);
}
return null;
}
}
}
Producer.java
package com.pc.producer;
import com.pc.product.Product;
import com.pc.storage.Storage;
public class Producer implements Runnable {
private Storage<Product> storage;
public Producer(Storage<Product> storage) {
this.storage = storage;
}
@Override
public void run() {
while (true) {
synchronized (storage) {
Product p = new Product("Product");
storage.put(p);
System.out.println(Thread.currentThread().getName() + "\t生产者: " + p);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Consumer.java
package com.pc.consumer;
import com.pc.product.Product;
import com.pc.storage.Storage;
public class Consumer implements Runnable{
private Storage<Product> storage;
public Consumer(Storage<Product> storage) {
this.storage = storage;
}
@Override
public void run() {
while(true){
Product p = storage.take();
if(p != null){
System.out.println(Thread.currentThread().getName() + "\t消费者: "+p);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Test.java
package com.pc.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.pc.consumer.Consumer;
import com.pc.producer.Producer;
import com.pc.product.Product;
import com.pc.storage.Storage;
public class Test {
public static void main(String[] args) {
Storage<Product> storage = new Storage<Product>();
Producer producer1 = new Producer(storage);
Producer producer2 = new Producer(storage);
Consumer consumer1 = new Consumer(storage);
Consumer consumer2 = new Consumer(storage);
Consumer consumer3 = new Consumer(storage);
Consumer consumer4 = new Consumer(storage);
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(producer1);
executorService.submit(producer2);
executorService.submit(consumer1);
executorService.submit(consumer2);
executorService.submit(consumer3);
executorService.submit(consumer4);
}
}
测试结果:
pool-1-thread-2 生产者: Product [no=1, name=Product]
pool-1-thread-4 消费者: Product [no=1, name=Product]
pool-1-thread-1 生产者: Product [no=2, name=Product]
pool-1-thread-6 消费者: Product [no=2, name=Product]
pool-1-thread-2 生产者: Product [no=3, name=Product]
pool-1-thread-4 消费者: Product [no=3, name=Product]
pool-1-thread-1 生产者: Product [no=4, name=Product]
pool-1-thread-6 消费者: Product [no=4, name=Product]
pool-1-thread-2 生产者: Product [no=5, name=Product]
pool-1-thread-1 生产者: Product [no=6, name=Product]
pool-1-thread-4 消费者: Product [no=5, name=Product]
pool-1-thread-6 消费者: Product [no=6, name=Product]
pool-1-thread-2 生产者: Product [no=7, name=Product]
pool-1-thread-1 生产者: Product [no=8, name=Product]
pool-1-thread-4 消费者: Product [no=7, name=Product]
pool-1-thread-6 消费者: Product [no=8, name=Product]
pool-1-thread-1 生产者: Product [no=9, name=Product]
pool-1-thread-2 生产者: Product [no=10, name=Product]
pool-1-thread-4 消费者: Product [no=9, name=Product]
pool-1-thread-6 消费者: Product [no=10, name=Product]
pool-1-thread-1 生产者: Product [no=11, name=Product]
pool-1-thread-2 生产者: Product [no=12, name=Product]
pool-1-thread-4 消费者: Product [no=11, name=Product]
pool-1-thread-6 消费者: Product [no=12, name=Product]
pool-1-thread-1 生产者: Product [no=13, name=Product]
pool-1-thread-5 消费者: Product [no=13, name=Product]
pool-1-thread-2 生产者: Product [no=14, name=Product]
pool-1-thread-6 消费者: Product [no=14, name=Product]