Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 2 of 2

Thread: Agent-Smoker output error help needed

  1. #1
    Junior Member
    Join Date
    Nov 2013
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Agent-Smoker output error help needed

    I am trying to implement the agent-smoker problem in Java: There are 3 smokers, and 1 agent. Each smoker has 1 of the 3 ingredients (matches, paper, tobacco). The agent has an infinite amount of all ingredients, and randomly puts 2 on the table. The smoker that is missing those 2 ingredients grabs it, rolls a cigarette, and this process repeats. Here is what I have so far:



    import java.util.ArrayList;
    import java.util.Random;
    class CigaretteSmokersProblem {
     
        public static void main(String[] args) {
            table smokingtable = new table();
     
            agent controlAgent = new agent(smokingtable);
     
            controlAgent.start();
     
            for (int i = 0; i < 3; i++)
            {
                // each smoker-thread gets the controlAgent, so the thread can wake up the agent and we don't have to do notifyAll();
                smoker smokerThread = new smoker(smokingtable, i, "Smoker " + Integer.toString(i+1), controlAgent);
                smokerThread.start();
            }
        }
    }
     
    class smoker extends Thread {
     
        private table smokingtable = new table();
        private String ingredient;
        private int ingredientNumber;
        private agent controlAgent;
     
        public smoker(table pSmokingtable, int pIngredientNumber, String pName, agent pAgent)
        {
            // only save the number of the ingredient, we'll get the ingredient's name while the thread is running
            ingredientNumber = pIngredientNumber;
            this.smokingtable = pSmokingtable;
            setName(pName);
            controlAgent = pAgent;
        }
     
        @Override
        public void run()
        {
            while(true)
            {
                ingredient = smokingtable.getSmokerIngredient(ingredientNumber);
     
                if (!smokingtable.hasIngredient(ingredient) && !smokingtable.isEmpty())
                {
                    System.out.println(getName() + " has " + ingredient + ".");
                    try {
                        doSmoke();
                        System.out.println(getName() + " tells the agent to start the next round.");
                        // the thread tells the agent to continue
                        controlAgent.wake();
                    } catch (Exception e) {}
                }
            }
        }
     
        public synchronized void doSmoke() throws Exception
        {
            System.out.println(getName() + " rolls the cigarette.");
            Thread.sleep(2500);
            System.out.println(getName() + " smokes.");
            Thread.sleep(2500);
            System.out.println(getName() + " has finished.");
        }
     
      }
     
    class agent extends Thread {
     
        private table smokingtable;
     
        public agent(table pSmokingtable)
        {
            smokingtable = pSmokingtable;
        }
     
        @Override
        public void run()
        {
            while(true)
            {
                try {
                    Thread.sleep(5000);
                } catch (Exception e) {}
                smokingtable.setAgentIngredients();
                // this triggers the smoker-threads to look at the table
                System.out.println("\n");
                System.out.println("The agents puts " + smokingtable.getAgentIngredients() + " on the table.");
                // pause the agent while one smoker thread is running
                pause();
            }
        }
     
        public synchronized void wake()
        {
            try
            {
                notify();
            } catch(Exception e){}
        }
     
     
        public synchronized void pause()
        {
            try
            {
                this.wait();
            } catch (Exception e) {}
        }
     
     
    }
     
    /*Class for creating table*/
    class table {
        //Variables for storing ingredients(tabacco,paper,matches)
        private ArrayList allIngredients  = new ArrayList();
        private ArrayList agentIngredients = new ArrayList();
     
        public table()
        {
            allIngredients .add("tabacco");
            allIngredients .add("paper");
            allIngredients .add("matches");
        }
        /*Function for setting two ingredients randomly*/
        public void setAgentIngredients()
        {
            Random random = new Random();
     
            agentIngredients.clear();
     
            ArrayList copyAllElements = (ArrayList) allIngredients .clone();
     
            int ingredient1 = random.nextInt(copyAllElements.size());
            agentIngredients.add(copyAllElements.get(ingredient1));
     
            copyAllElements.remove(ingredient1);
            int ingredient2 = random.nextInt(copyAllElements.size());
            agentIngredients.add(copyAllElements.get(ingredient2));
        }
        /*Function for checking weather the table is empty*/
        public boolean isEmpty()
        {
            return (agentIngredients.size() == 0);
        }
        /*Function for getting two ingredients that 
        are set previously by the function setAgentIngredients()*/
        public synchronized String getAgentIngredients()
        {
            notifyAll();
            return agentIngredients.toString();
        }
        /*Function for getting the ingredient 
        with the corresponding smoker*/
        public synchronized String getSmokerIngredient(int pIngredient)
        {
            try {
                this.wait();
            } catch (Exception e) {}
            return (String) allIngredients .get(pIngredient);
        }
        /*Function for Checking the smoker has the same ingredient 
        as in the table if so smoking is is not possible*/
        public boolean hasIngredient(String ingredientName)
        {
            return (agentIngredients.contains(ingredientName));
        }
     
        public synchronized void pause()
        {
            try {
                this.wait();
            } catch (Exception e) {}
        }
    }



    The output is usually correct,


    The agents puts [matches, tabacco] on the table.
    Smoker 2 has paper.
    Smoker 2 rolls the cigarette.
    Smoker 2 smokes.
    Smoker 2 has finished.
    Smoker 2 tells the agent to start the next round.


    But sometimes, the order gets messed up for some reason:

    Smoker 3 has matches.
    Smoker 3 rolls the cigarette.
    The agents puts [paper, tabacco] on the table.
    Smoker 3 smokes.
    Smoker 3 has finished.
    Smoker 3 tells the agent to start the next round.

    Smoker 3 has matches and rolls the cigarette before the agent puts the resources on the table.
    Can anybody figure out what part of my code is wrong?
    Thanks!


  2. #2
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,517
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Agent-Smoker output error help needed

    There is probably nothing "wrong" with your code. From "Introduction to Programming Using Java, Sixth Edition," by David J. Eck, Chapter 12:
    In a normal, single-threaded program, things happen in a definite, predictable order from beginning to end. In a multi-threaded program, there is a fundamental indeterminacy. You can't be sure what order things will happen in. This indeterminacy is what makes parallel programming so difficult!

Similar Threads

  1. Output error
    By mcdanielnc89 in forum What's Wrong With My Code?
    Replies: 1
    Last Post: October 30th, 2013, 09:49 PM
  2. logical error in output
    By siyanor in forum What's Wrong With My Code?
    Replies: 1
    Last Post: May 28th, 2013, 04:22 AM
  3. [SOLVED] How do I get the one part of the needed output for quarterly sales-statistics?
    By SOG in forum What's Wrong With My Code?
    Replies: 32
    Last Post: June 28th, 2012, 10:04 AM
  4. I/O Program output error
    By gatorsgirl in forum File I/O & Other I/O Streams
    Replies: 8
    Last Post: April 11th, 2012, 04:18 PM
  5. Help needed to figure out why I keep getting error messages in Eclipse
    By RookieCodeWriter in forum What's Wrong With My Code?
    Replies: 1
    Last Post: March 18th, 2012, 11:31 AM