日期:2014-05-17 浏览次数:21186 次
3、深入解析Apache Mina源码(3)——Mina的线程池模型
?
一、生产者消费者问题
?
做为苦逼的程序员的我们基本没有不知道生产者消费者问题的,这个经典的问题充分体现了进程同步的问题,还是简单的说下它的概念,生产者和消费者是两个线程,生产者线程生产物品放到空的缓冲区内(可能是一个list),消费者线程从缓冲区内取出物品进行消费并释放缓冲区,缓冲区有个固定大小,当生产者线程将缓冲区填充满时,生产者线程处于等待状态,等待消费者线程消费;当缓冲区消费空了后,消费者线程处于等待状态,等待生产者线程进行生产。当然生产者和消费者也可以有多个线程充当,但是操作的进程地址空间却只能是同一个。
这个经典的问题体现了多线程编程的一些要注意的地方,比如对同一资源进行访问所产生的互斥和同步问题。
下面看下对生产者消费者问题的实现。
物品类:
package com.lifanghu.procon;
/**
 * 食物
 * @author lifh
 * @mail wslfh2005@163.com
 * @since 2012-6-22 上午08:13:34
 * @name com.lifanghu.procon.Food.java
 * @version 1.0
 */
public class Food {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
?
?缓冲区:
package com.lifanghu.procon;
import java.util.ArrayList;
import java.util.List;
/**
 * 容器,缓冲区
 * @author lifh
 * @mail wslfh2005@163.com
 * @since 2012-6-22 上午08:33:56
 * @name com.lifanghu.procon.Container.java
 * @version 1.0
 */
public class Container {
    //缓冲区大小 
    private int size;
    private List<Food> foods;
    public Container(int size) {
        this.size = size;
        foods = new ArrayList<Food>(size);
    }
    public synchronized void poll(Food food) {
        while (foods.size() >= size) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        foods.add(food);
        notifyAll();
    }
    public synchronized Food offer() {
        Food food = null;
        while (foods.size() == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        food = foods.remove(foods.size() - 1);
        notifyAll();
        return food;
    }
}
?
?生产者:
package com.lifanghu.procon;
/**
 * 生产者
 * @author lifh
 * @mail wslfh2005@163.com
 * @since 2012-6-22 上午08:13:26
 * @name com.lifanghu.procon.Producer.java
 * @version 1.0
 */
public class Producer implements Runnable {
    private Container container;
    public Producer(Container container) {
        super();
        this.container = container;
    }
    public void run() {
        for (int i = 0; i < 10; i++) {
            Food food = new Food();
            food.setName("馒头" + i);
            System.out.println("生产者生产出" + food.getName());
            container.poll(food);
            try {
                Thread.sleep((long) (Math.random() * 3000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
?
?消费者:
package com.lifanghu.procon;
/**
 * 消费者
 * @author lifh
 * @mail wslfh2005@163.com
 * @since 2012-6-22 上午08:13:52
 * @name com.lifanghu.procon.Consumer.java
 * @version 1.0
 */
public class Consumer implements Runnable {
    private Container container;
    public Consumer(Container container) {
        super();
        this.container = container;
    }