Synchronization of methods in java

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Time
    New Member
    • Jan 2010
    • 77

    Synchronization of methods in java

    Am having difficulty in understanding how code given in Complete ref. of Java

    Code:
    class book
    {
    	int n;
    	boolean val=false;
    	synchronized int get()
    	{
    		while(!val)
    		{
    			try
    			{
    				wait();
    			}
    		
    		catch(InterruptedException e)
    		{
    			System.out.println("Caught the exception"+e);
    		}
    		}
    		System.out.println("Got:"+n);
    		val=false;
    		notify();
    		return n;
    	}
    	synchronized void put(int n)
    	{
    		while(val)
    		{
    			try
    			{
    				wait();
    			}
    		catch(InterruptedException e)
    		{
    			System.out.println("Caught the exception"+e);
    		}
    		}
    		this.n=n;
    		val=true;
    		System.out.println("Put:"+n);
    		notify();
    	}
    }
    class producer implements Runnable
    {
    	book b;
    	producer(book b)
    	{
    		this.b=b;
    		new Thread(b,"producer").start();
    	}
    	public void run()
    	{
    		int i=0;
    		while(true)
    		{
    			b.put(i++);
    		}
    	}
    }
    class consumer implements Runnable
    {
    	book b;
    	consumer(book b)
    	{
    		this.b=b;
    		new Thread(this,"consumer").start();
    	}
    	public void run()
    	{
    		int i=0;
    		while(true)
    		{
    			b.get();
    		}
    	}
    	
    }
    class PCfixed
    {
    	public static void main(String a[])
    	{
    		book b=new book();
    		new producer(b);
    		new consumer(b);
    		System.out.println("Press control-c to stop!");
    	}
    }
    This code works as stated in book;
    value gets put by producer and consumed by consumer.
    put:1
    get:1
    ..so on..
    how come book class gives no error ; as its using notify(),wait() functions of Thread class without extending it.
    Next one is when we call producer(b); it goes in its constructor; which calls start ;taking execution in run() of it.. which calls put(i); in which while loop doesnt execute as value is set to false so by wait() it'll go to get and hence consumer will work 1st...so, where am i mistaking?
  • pbrockway2
    Recognized Expert New Member
    • Nov 2007
    • 151

    #2
    Originally posted by Time
    how come book class gives no error ; as its using notify(),wait() functions of Thread class without extending it.
    notify() - "Wakes up a single thread that is waiting on this object's monitor" - and wait() - "Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object" - are methods of Object not Thread.

    Comment

    • pbrockway2
      Recognized Expert New Member
      • Nov 2007
      • 151

      #3
      Originally posted by Time
      put(i); in which while loop doesnt execute as value is set to false so by wait() it'll go to get
      put() gets called from the run() method of the producer as you say.

      Now in put() the waiting only happens when (and while) val is true. If val is false the put() method goes on and prints the console message.

      Perhaps I am missing what you are confused about.

      Comment

      • Time
        New Member
        • Jan 2010
        • 77

        #4
        exactly.. put will work when value of val is true but when we call it for the first time its value is false... as its set to false in book class..
        But in output put method works first; i.e. it displays the value first and same one is accepted by get.. after put has done with displaying value..
        but according to the code, put is not the one which will execute first..

        Comment

        • pbrockway2
          Recognized Expert New Member
          • Nov 2007
          • 151

          #5
          put will work when value of val is true
          No - put() will wait while val is true. That's what "while(val){wai t();}" means. put() will print the console message after val has stopped being true. Ie when val is false.

          The first time put() is called val is false so no wait()ing happens. But the rest of the put() method - the four lines after the while block - occurs as normal.

          Comment

          • Time
            New Member
            • Jan 2010
            • 77

            #6
            Thanks a lot...it was really very helpful..i was missing the main point..
            But i guess am still confused about what exactly will be the sequence of execution..
            I'll write down what i make out of execution sequence; you point out where am i going wrong.. if it is ok with you.
            1.Object of book is created with default constuctor.
            2.Object of producer is created; it calls constuctor of it; which is having start method; which makes execution go in run() of producer,..wher e the val is false so wait won't get called; and one value will be displayed...aft er that notify() will wake up the thread that is in objects monitor.....But till now only put() has been called and its not in wait() state; so no point of waking it up...and further put is in while loop so how come it will ever call get...the next line of code.... even if we use wait; inside run of producer the while condition is always true; without letting execution go out of it... ???messed up

            Comment

            • pbrockway2
              Recognized Expert New Member
              • Nov 2007
              • 151

              #7
              1.Object of book is created with default constuctor.
              2.Object of producer is created; it calls constuctor of it; which is having start method; which makes execution go in run() of producer,..wher e the val is false so wait won't get called; and one value will be displayed...aft er that notify() will wake up the thread that is in objects monitor...
              OK. The notify picks one of the threads that might be waiting (if there is one) and takes it out of its "waiting" state.

              But till now only put() has been called
              I'm not sure about that. We don't know if the consumer thread has been created and started at this point. Remember main() and the creation of the objects happens in one thread and the put()s and get()s all happen on other threads. When notify is called the other other thread may or may not have called get(): we don't know.

              and its [put()'s] not in wait() state; so no point of waking it up...
              Yes. The thread executing put() is not waiting. So it doesn't get woken. Actually there is no mystery what put() does once it calls notify(): it returns! put() has finished.

              and further put is in while loop so how come it will ever call get.
              I don't understand what you mean by this. put() has returned and is finished. The wait while loop has well and truly finished. Execution has passed back to producer's run() method. Is that the while loop you are talking about?

              That loop continually calls put() - but get() still gets called ... in another thread! (the consumer thread that gets created eventually).

              ...the next line of code.... even if we use wait; inside run of producer the while condition is always true; without letting execution go out of it... ???
              I'm not sure I understand what you are getting at here. But you seem to be losing sight of the fact that there are two different threads here. (not counting main() which is in a third thread). Try following the flow from line to line with your finger. But the thing is you'll have to use two fingers because there are two threads.

              It's almost like two programs happening at once. One of them gets into a tight loop "while(true){ge t();}" and one of them gets into a tight loop "while(true){pu t();}". Different fingers are pointing to these different while loops. Both are happening.

              Occasionally the flow of code being traced by each finger will be made to wait (until val has a certain value) but, other than that, both fingers (threads) trace their own, independent, paths through the code.

              Comment

              • Time
                New Member
                • Jan 2010
                • 77

                #8
                Please check this as well.
                Is it the case that; as put and get are in Q class; they are in Q object's monitor.. am bothered about objects monitor; as notify() will wake-up a thread which is in objects monitor..
                If am right till this point..after executing put() once..notify() will return as you said..
                so; is it the case that as soon as notify() is executed; get can now access the resources..i.e. variables of Q class; meaning val which is now true; making get to come out of its while(!val) {..} loop; and get will be executed now..and at the same time put is in wait state but as get is executed once it will notify() and then put will come out of its wait state..
                so the same procedure will continue...
                Last thing am not clear about is; what exactly makes a program run more than one thread i.e. functions...is it because we have implemented runnable in producer and consumer... but what is making main() not to wait till producer class is done with creating object and execute the next line simultaneously? its not implementing runnable..is it because it has called producer and producer is the one which is implementing runnable; so it gives main() freedom to execute next line without letting finishing the present one first??

                Comment

                • pbrockway2
                  Recognized Expert New Member
                  • Nov 2007
                  • 151

                  #9
                  I'm not 100% sure about what you're saying in the first paragraph, but it sounds right...

                  As for what allows the program to begin with one thread (where main() runs) but create multiple threads, and for main() to "keep going", as it were, without having to wait: I think the answer lies in the fact that start() returns immediately. main() calls a constructor which in turn creates and starts a new thread. The constructor returns and main() is free to continue.

                  Comment

                  • Time
                    New Member
                    • Jan 2010
                    • 77

                    #10
                    But how come start() can return immediately? I mean it is the one which implicitly calls run()...am not sure whether it actually calls; or some method is used.. i suppose it calls as execution goes in run().. so start() is calling run(); it can't return until run() is done..?

                    Comment

                    • pbrockway2
                      Recognized Expert New Member
                      • Nov 2007
                      • 151

                      #11
                      What the API docs say is "Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
                      The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method)".

                      Think of it like a person starting a race. This person causes calls a start method for each of the race participants (each of whom begin to run). But now we have multiple threads going simultaneously: one for each race participant and one for the starter.

                      The important thing is that the starter does not have to wait around at the side of the track while the race is being run. They are in their own thread and go on to do ther things once they have invoked the particpant's start().

                      Comment

                      • Time
                        New Member
                        • Jan 2010
                        • 77

                        #12
                        Thanks a lot PBROCKWAY2.
                        it was really very helpful.

                        Comment

                        • pbrockway2
                          Recognized Expert New Member
                          • Nov 2007
                          • 151

                          #13
                          You're welcome.

                          (this portion added to lengthen the post...)

                          Comment

                          Working...