wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Synchronization Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Synchronization" Watch "Synchronization" New topic
Author

Synchronization

Tom Mark
Greenhorn

Joined: Jun 15, 2011
Posts: 27
Don't understand the following statement:

Threads calling non-static synchronized methods in the same class will
only block each other if they're invoked using the same instance and if
they're called using two different instances, they get two locks, which do not interfere with each other.


To which instance do I have to pay attention for?




As I understand the code above has two different instances and according to previous rule instances should get two locks, which means that Threads do not interfere with each other.


But some guys in forum says that d.chat() method is called on the same instance by both the threads...


Suppose they are right. But what about this code?



The following Threads have one instance "runnable"

But SCJP test says that methods x.a() in thread1, and y.a() in thread2 are called on different instances and they
do not block each other.

So which instance determines whether to block or not???
Eduardo Mineo
Ranch Hand

Joined: Sep 26, 2011
Posts: 63

Hi Tom.

When I was getting myself prepared to OCJP, I realized that confusion is the aim of the test. So, get used to it

In fact, you must pay attention for all instance in play. Ever. But, in this case, pay even more attention to "static Dudes d". Only one instance of Dudes is in play, so you have two threads, represented by two instance of DudesChat making calls to only one instance of Dudes, created only one time on d = new Dudes().

Can you see the difference?

--eduardo
Nitesh Nandwana
Ranch Hand

Joined: Jun 07, 2011
Posts: 115

Eduardo Mineo wrote:

When I was getting myself prepared to OCJP, I realized that confusion is the aim of the test.
--eduardo


You're wrong if you 're confused , means you've lost everything
Eduardo Mineo
Ranch Hand

Joined: Sep 26, 2011
Posts: 63

Nitesh, I really think confusion is a stage of being prepared for OCJP exam. And being prepared for OCJP exam don't mean you're a good java programmer at all. It just mean that you are prepared to break silly tricky questions about java details.

Anyway, SCJP was a tricky test and when I took OCJP, I was expecting a tricky, dirty, dishonest test, but in fact, I found a very good, straightforward and conceptual test. But all the same, getting confused is a good signal, a signal that you, at least, know you're not understanding something. It's better than think that know something and, in fact, don't.

Tom, I see now that you have put another sample, ThreadDemo. Pay attention for x and y objects. They are two instances of ThreadDemo. Even though you have only one instance of runnable, x still is one instance of ThreadDemo and y is still another instance of ThreadDemo. So, the "a()" method will not block the thread because it's a non-static method of ThreadDemo class, all right?
Steven Elliott
Greenhorn

Joined: Mar 28, 2002
Posts: 14
I'm just a Greenhorn but to teach is to learn...

Threads calling non-static synchronized methods in the same class will
only block each other if they're invoked using the same instance and if
they're called using two different instances, they get two locks, which do not interfere with each other.


Quick review:
  • non-static methods are instance methods and execute within the scope of the instance.
  • static methods are class methods and execute within the scope of the class.


  • Your quote states that the threads are calling non-static or instance methods and not class methods. I'll cover both but first non-static methods.

    In order to execute instance methods you need to create an instance. For example MyClass newInstance = new MyClass();
    Lets say that MyClass has a non-static synchronized method as follows;

    public synchronized void instanceSyncMethod() { System.out.println("calling instanceSyncMethod()"); }

    newInstance is now an object with its own variables and methods. If newInstance is passed to two threads running simultaneously then both threads are using the same instance. So when thread1 calls newInstance.instanceSyncMethod() and thread2 calls newInstance.instanceSyncMethod() they are both asking the same object to do the same thing. Because the method is synchronized meaning only one thread can execute the code at a time the first thread to obtain the lock will execute and the second thread will need to wait/block.

    Lets create another instance of MyClass and call it newInstance2 - MyClass newInstance2 = new MyClass()
    newInstance2 is a separate copy of MyClass and has its own variables and methods. Now pass newInstance to thread1 and newInstance2 to thread2. When thread1 calls newInstance.instanceSyncMethod() and thread2 calls newInstance2.instanceSyncMethod() the two threads are calling the same method but on two different instances. Since each instance has its own variables and methods the threads run without blocking.

    Hopefully that makes the non-static part clearer.

    The static part requires that you change the scope (and thinking) from instance to class.

    Lets say that MyClass has a static synchronized method as follows;

    public static synchronized void staticSyncMethod() { System.out.println("calling MyClass.staticSyncMethod()"); }

    We have already seen that when thread1 calls newInstance.instanceSyncMethod() and thread2 calls newInstance2.instanceSyncMethod() that the two threads run without blocking. But what happens when they both call staticSyncMethod() even on different instances of MyClass?

    Because staticSyncMethod() is a static method only one copy of this method will ever exist and is referenced from the MyClass object. In fact when thread1 or thread2 calls newInstance.staticSyncMethod() the compiler is building a call to MyClass.staticSyncMethod(). The ability to use newInstance or newInstance2 to reference staticSyncMehtod() is allowed by the compiler as a convenience method but the code generated always translates the code to reference the class object.

    If you were to correctly program the code thread1 would call:
    MyClass.staticSyncMethod();
    and thread2 would call:
    MyClass.staticSyncMethod();

    It makes it easier to see that both threads are calling the same method in the same scope and by calling this method one thread would need to block as the other executed.

    Make sense?
    Tom Mark
    Greenhorn

    Joined: Jun 15, 2011
    Posts: 27
    Eduardo Mineo wrote:Hi Tom.

    When I was getting myself prepared to OCJP, I realized that confusion is the aim of the test. So, get used to it

    In fact, you must pay attention for all instance in play. Ever. But, in this case, pay even more attention to "static Dudes d". Only one instance of Dudes is in play, so you have two threads, represented by two instance of DudesChat making calls to only one instance of Dudes, created only one time on d = new Dudes().

    Can you see the difference?

    --eduardo


    I see that both threads shares the same method on the same instance "new Dudes" which was instantiated only once cause it is static.

    The next code also shows that two threads shares same methods x.a(), y.a() which are with different instances.
    Here another one which confuses me.




    Eduardo Mineo
    Ranch Hand

    Joined: Sep 26, 2011
    Posts: 63

    I see that both threads shares the same method on the same instance "new Dudes" which was instantiated only once cause it is static.


    Perfect. So, the lock would be on Dudes, not on DudesChat. Therefore, the guys who told you two threads accessing the same instance are right.



    What's the fun about this code? It shows you that there are 2 threads represented by 2 different instances. Why 2 instances? Look at main() method. It's the same as:



    You have two instances of Chess, therefore, two locks for Chess. So, move() will not block and you get a mixed result.

    Don't get panic, thread is not trivial.
    Tom Mark
    Greenhorn

    Joined: Jun 15, 2011
    Posts: 27
    ok. I'll write what I have just understood. Correct me if I'm wrong.

    The code fragment from my last message means that..


    .. there are two threads with two different instances(new Chess()). Each instance has its own method run() and executes it and calls method move(). Threads don't share these methods with each other.





    This code fragment has two threads but one instance(runnable). It executes the same method run() on the same instance. But run() method owns methods with different instances.


    As I see everything depends on what do we have in a run() method. Am I wrong?
    Eduardo Mineo
    Ranch Hand

    Joined: Sep 26, 2011
    Posts: 63

    .. there are two threads with two different instances(new Chess()). Each instance has its own method run() and executes it and calls method move(). Threads don't share these methods with each other.


    Yes, exactly.

    This code fragment has two threads but one instance(runnable). It executes the same method run() on the same instance. But run() method owns methods with different instances.


    The run() methods don't own two instances. Since this method was implemented inside an anonymous class, it has access for two different local instances from main() method: x and y. In fact, main() method owns x and y.

    PS: remember, Runnable anonymous class has access to x and y because these local variables were marked as final.
     
     
    subject: Synchronization
     
    Similar Threads
    help me with Thread Problem
    Doubt with thread
    chapter 9 self test Q.15
    concurrent acess
    Thread's tangle