在Java中实现信号量



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

猫会检查蜥蜴(一旦醒来),如果有很多人一次越过路径,它就会吃掉它们。这个想法是要让蜥蜴交叉和吃饭,而世界没有从猫线中断出来。

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

我有一个想法只需要额外的推动,所以我可以开始裂开它。

编辑到代码中以显示我的问题的位置。

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)

这正是 java.util.concurrent.Semaphore的目的。

最新更新