模拟鸟和鱼的生态池塘

问题来源于:http://topic.csdn.net/u/20120312/12/5ecd2514-362d-4693-ba3e-852d69956434.html

一个池塘,有很多鸟和很多鱼,鸟每分钟产生一个后代,鱼每30秒钟产生2个后代。鸟每10秒钟要吃掉一条鱼。建一个池塘,初始化一些鱼和鸟,看看什么时候鸟把鱼吃光。


本来不算复杂,但是既然写了,就记录下来吧。


import java.util.concurrent.CountDownLatch;

public class AboutFishBird {

    public static void main(String[] args) throws Exception {
        simulate(24, 5);
    }

    private static void simulate(int initFish, int initBird) throws Exception {
        World world = new World();
        world.fishNum = initFish;
        world.birdNum = initBird;

        FishKeeper fk = new FishKeeper(world);
        BirdKeeper bk = new BirdKeeper(world);
        fk.start();
        bk.start();
        Thread.sleep(100); // 等待两个线程启动完毕

        while (world.fishNum > 0) {
            synchronized (world) { // 在子线程进入wait()前,世界时间不会开始流逝
                world.token = new CountDownLatch(2);
                world.time += 10; // 世界时间向前流逝
                world.notifyAll(); // 通知两个线程可以工作了
            }
            world.token.await(); // 跳动后,等待两个线程完成本次流逝时间的计算过程
            System.out.println("[" + world.time + "] fish:" + world.fishNum + ", bird:" + world.birdNum);
        }
        System.exit(0);
    }
}

/**
 * 世界环境
 */
class World {
    long time;
    int fishNum;
    int birdNum;
    CountDownLatch token;
}

/**
 * 鱼群管理器
 */
class FishKeeper extends Thread {
    private World world;

    FishKeeper(World world) {
        super("FishKeeper");
        this.world = world;
    }

    public void run() {
        synchronized (world) { // 防止并发修改冲突
            while (world.fishNum > 0) {
                try {
                    world.wait(); // 等待主线程通知时间已经流逝
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                if (world.time % 30 == 0) { // 每30秒生小鱼
                    world.fishNum += 2 * world.fishNum;
                }
                world.token.countDown(); // 记录工作计算已经完成
            }
        }
    }
}

/**
 * 鸟群管理器
 */
class BirdKeeper extends Thread {
    private World world;

    BirdKeeper(World world) {
        super("BirdKeeper");
        this.world = world;
    }

    public void run() {
        synchronized (world) { // 防止并发修改冲突
            while (world.fishNum > 0) {
                try {
                    world.wait(); // 等待主线程通知时间已经流逝
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                if (world.time % 10 == 0) {
                    world.fishNum -= world.birdNum; // 每10秒吃一次鱼
                    if (world.time % 60 == 0) {
                        world.birdNum += world.birdNum; // 每60秒生小鸟
                    }
                }
                world.token.countDown(); // 记录工作计算已经完成
            }
        }
    }
}

—— 20131030:因is_zhoufeng提出的死锁缺陷,做出了调整,将同步范围扩大。

你可能感兴趣的:(thread,exception,工作,Class,import)