模拟鸟和鱼的生态池塘

来源:互联网 发布:淘宝买监控硬盘靠谱吗 编辑:程序博客网 时间:2024/04/27 04:14

问题来源于: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提出的死锁缺陷,做出了调整,将同步范围扩大。