日期:2014-05-17  浏览次数:20891 次

【端午节礼物大放送】深入解析Apache Mina源码(3)——Mina的线程池模型


1、深入解析Apache Mina源码(1)——Mina的过滤器机制实现

2、深入解析Apache Mina源码(2)——Mina的事件模型

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;
    }