在java中实现信号量

时间:2012-10-22 04:37:27

标签: java multithreading

我有一些生成线程的代码(蜥蜴) 它也是一个猫线。

猫检查蜥蜴(一旦它醒来),如果有许多人一次穿过一条路,就会吃掉它们。这个想法是让蜥蜴穿过并吃掉,而世界还没有“结束”,因为猫线的中断。

我需要使用信号量来控制它。

我有这个想法只需要额外推动所以我可以开始解决它。

我已编辑代码以显示我的问题所在。

import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;


public class LizardsSync 
{
    /*
     * Set this to the number of seconds you want the lizard world to
     * be simulated.  
     * Try 30 for development and 120 for more thorough testing.
     */
    private static int WORLDEND = 30;

    /*
     * Number of lizard threads to create
     */
    private static int NUM_LIZARDS =20;

    /*  
     * Maximum lizards crossing at once before alerting cats
     */
    private static int MAX_LIZARD_CROSSING = 4;

    /*
     * Maximum seconds for a lizard to sleep
     */
    private static int MAX_LIZARD_SLEEP_TIME = 3;

    /*
     * Maximum seconds for a lizard to eat
     */
    private static int MAX_LIZARD_EAT_TIME = 5;

    /*
     * Number of seconds it takes to cross the driveway
     */
    private static int CROSS_TIME = 2;

    /*
     * Number of seconds for the cat to sleep.
     */
    private static int MAX_CAT_SLEEP;

    /*
     * A counter that counts the number of lizzards crossing sago to monkey grass
     */
    int numCrossingSago2MonkeyGrass = 0;

    /*
     * A counter that counts the number of lizzards crossing monkey grass to sago
     */
    int numCrossingMonkeyGrass2Sago = 0;

    /**
     * A semaphore to protect the crossway. 
     * only the max amount of lizards can cross so the cat wont 'play'
    */
    Semaphore semaphoreCrossway = new Semaphore(MAX_LIZARD_CROSSING,true);

    /**
     * A semaphore for mutual exclusion.
     */
    Semaphore mutex = new Semaphore(4);

    // on both semaphores, you can call acquire() or release()
    /*
     * Indicates if the world is still running.
     */
    private static boolean running = true;

    /*
     * Indicates if you want to see debug information or not.
     */
    private static boolean debug = true;


    public void go()
    {
        ArrayList<Thread> allThreads = new ArrayList<Thread>();

        // create all the lizzard threads
        for (int i=0; i < NUM_LIZARDS; i++) 
        {       allThreads.add(new LizardThread(i) );
            allThreads.get(i).start();
}
        // create the cat thread
        Thread CatThread = new CatThread();
         CatThread.start();

        // let the world run for a while
        sleep (WORLDEND);

        // terminate all threads
        running = false;
        // wait until all threads terminate by joining all of them
        for (int i=0; i < NUM_LIZARDS; i++) {
            try {
               allThreads.get(i).join();
            } catch (InterruptedException ex) {
                System.err.println ("unable to join thread, " + ex.getMessage());
            }
        }
    }
       /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // starts the program
        new LizardsSync().go();
    }

     /**
     * Models a cat thread.
     */
    public class CatThread extends Thread {


        /**
         * @see java.lang.Runnable.
         */
        @Override
        public void run() 
        {   
            // you must finish this method

            while (running) {
               // sleep for a while
               catSleep();

               // check on lizzards
               checkCrossway();
            }
        }

        /**
         * Puts cat thread to sleep for a random time.
         */
        public void catSleep()
        {
            int sleepSeconds  = 1 + (int)(Math.random()*MAX_CAT_SLEEP);

            if (debug) {
                System.out.println ("Cat is sleeping for " + sleepSeconds + " seconds.");
                System.out.flush();
            }
            try {
                sleep(sleepSeconds*1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
            }
            if (debug) {
                System.out.println ("Cat awakes.");
                System.out.flush();
            }
        }

        /**
         * Simulates cat checking the crossway.
         */
        public void checkCrossway()
        {
            if (numCrossingMonkeyGrass2Sago + numCrossingSago2MonkeyGrass > MAX_LIZARD_CROSSING) {
                System.out.println ("The cat says yum!");
                System.out.flush();
                     System.exit(-1);
            }
       }
    }

    /**
     * Models a lizard thread.
     */
    public class LizardThread extends Thread {

        private int _id;

        /**
         * Creates a new lizard thread.
         * 
         * @param id the id assigned to the lizard thread
         */
        public LizardThread(int id)
        {
            _id = id;
        }

        /**
         * @see java.lang.Runnable.
         */
        @Override
        public void run() 
        {    
            while (running) {
               // sleep for a while in sago
               lizardSleep();
               // wait until safe to cross from sago to monkey grass
               sagoToMonkeyIsSafe();
               // cross path to monkey grass
               crossedOverToMonkey();
               // eat in the monkey grass
               lizardEat();
               // wait untill its safe to cross back to sago
               monkeyToSagoIsSafe();
               // cross from cross monkey grass to sage
               crossMonkeyToSago();
            }
        }

        /**
         * This tests if it is safe to travel from sago to monkey.
         * Finish this.
         */
        public void sagoToMonkeyIsSafe()
        {
            if (debug) {
                System.out.println ("Lizard [" + _id + "] checks sago -> monkey grass.");
                System.out.flush();
            }

            // you must add code here
            // use a semaphore 


            if (debug) {
                System.out.println ("Lizard [" + _id + "] thinks sago -> monkey grass is safe.");
                System.out.flush();
            }
        }

        /**
         * Indicates that lizard crossed over to monkey grass.
         * Finish this.
         */
        public void crossedOverToMonkey()
        {
            if (debug) {
                System.out.println ("Lizard [" + _id + "] made it to monkey grass.");
                System.out.flush();
            }

            // add code here
        }


        /**
         * This tests if it is safe to travel from monkey to sago.
         * Finish this.
         */
        public void monkeyToSagoIsSafe()
        {
            if (debug) {
                System.out.println ("Lizard [" + _id + "] checks monkey grass -> sago.");
                System.out.flush();
            }

            // you must add code here
            // use a semaphore 

            if (debug) {
                System.out.println ("Lizard [" + _id + "] thinks monkey grass -> sago is safe.");
                System.out.flush();
            }
        }

        /**
         * Indicates that lizard crossed over to sago.
         * Finish this.
         */
        public void crossedOverToSago()
        {
            if (debug) {
                System.out.println ("Lizard [" + _id + "] made it to sago.");
                System.out.flush();
            }

            // add code here
        }

        /**
         * Indicates that lizard is crossing over from monkey to sago.
         * Finish this
         */
        void crossMonkeyToSago()
        {
            if (debug) {
                System.out.println ("Lizard [" + _id + "] is crossing monkey grass to sago.");
                System.out.flush();
            }

            numCrossingMonkeyGrass2Sago++;

            // simulate walk
            try {
                sleep(CROSS_TIME*1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
            }

            numCrossingMonkeyGrass2Sago--;
        }

        /**
         * Indicates that lizard is crossing over from sago to monkey. 
         */
        void crossSagoToMonkey()
        {

            if (debug) {
                System.out.println ("Lizard [" + _id + "] is crossing sago to monkey grass.");
                System.out.flush();
            }

            numCrossingSago2MonkeyGrass++;

            // simulate walk
            try {
                sleep(CROSS_TIME*1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
            }

            numCrossingSago2MonkeyGrass--;
        }


        /**
         * Puts lizard thread to sleep for a random amount of time.
         */
        public void lizardSleep()
        {
            int sleepSeconds  = 1 + (int)(Math.random()*MAX_LIZARD_SLEEP_TIME);

            if (debug) {
                System.out.println ("Lizard [" + _id + "] is sleeping for " + sleepSeconds + " seconds.");
                System.out.flush();
            }
            try {
                sleep(sleepSeconds*1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
            }
            if (debug) {
                System.out.println ("Lizard [" + _id + "] awakes.");
                System.out.flush();
            }
        }

        /**
         * Simulates lizard eating for a random amount of time.
         */
        public void lizardEat()
        {
            int eatSeconds  = 1 + (int)(Math.random()*MAX_LIZARD_EAT_TIME);

            if (debug) {
                System.out.println ("Lizard [" + _id + "] is eating for " + eatSeconds + " seconds.");
                System.out.flush();
            }
            try {
                sleep(eatSeconds*1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
            }
            if (debug) {
                System.out.println ("Lizard [" + _id + "] finished eating.");
                System.out.flush();
            }
        }
    }


    /**
     * Puts current thread to sleep for a specified amount of time.
     * 
     * @param seconds the number of seconds to put the thread to sleep
     */
    private static void sleep(int seconds)
    {
        try {
            Thread.sleep(seconds*1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

此代码现在写了类似这样的内容

Cat awakes.
The cat says yum!
Lizard [8] finished eating.
Lizard [0] is sleeping for 1 seconds.
Lizard [8] checks monkey grass -> sago.
Lizard [1] finished eating.
Lizard [8] thinks monkey grass -> sago is safe.
Lizard [1] checks monkey grass -> sago.
Lizard [8] is crossing monkey grass to sago.
Lizard [1] thinks monkey grass -> sago is safe.Java Result: -1
BUILD SUCCESSFUL (total time: 5 seconds)

1 个答案:

答案 0 :(得分:2)

这正是java.util.concurrent.Semaphore的用途。