多线程案例:生产者和消费者
1.生产和消费的产品抽象类:
public abstract class Product {
public String name;
public abstract String toString();
}
2.一个具体的产品类:
public class AProduct extends Product {
public AProduct(String name) {
this.name = name;
// TODO Auto-generated constructor stub
}
public String toString() {
// TODO Auto-generated method stub
return this.name;
}
}
3.容器类(仓库):
import java.util.ArrayList;
/*
* 存放生产者和消费者的产品队列
* */
public class Container {
private ArrayList arrList = new ArrayList();
private int LENGTH = 10;
public boolean isFull() {
return arrList.size()==LENGTH;
}
public boolean isEmpty() {
return arrList.isEmpty();
}
/* 如果此处不加synchronized锁,那么也可以再调用push的地方加锁
* 既然此处加了锁,那么再别的地方可以不加锁
*/
public synchronized void push(Object o) {
arrList.add(o);
}
// 如果此处不加synchronized锁,那么也可以再调用push的地方加锁
public synchronized Object pop() {
Object lastOne = arrList.get(arrList.size()- 1);
arrList.remove(arrList.size()- 1);
return lastOne;
}
}
4.休息一会,生产者和消费者都要休息,因此作为抽象基类:
public abstract class Sleep {
public void haveASleep() throws InterruptedException {
Thread.sleep((long)(Math.random()* 3000));
}
}
/*
* 消费者线程
* */
public class Consumer extends Sleep implements Runnable {
private Container contain =null;
public Consumer(Container contain) {
this.contain = contain;
}
public void run() {
// TODO Auto-generated method stub
while(true) {
synchronized(contain) {
while(contain.isEmpty()) {
try{
contain.wait();
}catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
consume();//消费
try {
haveASleep();
}catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(contain) {
contain.notify();
}
}
}
private void consume() {
Product a = (AProduct)contain.pop();
System.out.println("消费了一个产品"+ a.toString());
}
}
/*
* 生产者线程
* */
public class Producator extends Sleep implements Runnable {
private Container contain = null;
public Producator(Container contain) {
super();
this.contain = contain;
}
public void run() {
// TODO Auto-generated method stub
while(true) {
synchronized(contain) {
while(contain.isFull()) {
try{
contain.wait();// 阻塞当前线程,当前线程进入等待队列。这个时候只有等待别的线程来唤醒自己了。
}catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
producer();// 生产一个产品
try {
haveASleep();
}catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(contain) {
contain.notify();// 唤醒等待队列中正在等待的第一个线程,让其执行。
}
}
}
public void producer() {
Product aProduct = new AProduct("pp:"+String.valueOf((int)(10*Math.random())));
System.out.println("生产了一个产品:"+ aProduct.toString());
contain.push(aProduct);
}
}
5. 写一个测试:
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Container contain = new Container();
Producator p = new Producator(contain);
Consumer c = new Consumer(contain);
Thread pt =new Thread(p);
Thread ct =new Thread(c);
pt.start();
ct.start();
}
}