• Post Reply Bookmark Topic Watch Topic
  • New Topic

Accesing two synchronized methods  RSS feed

 
Ramesh Kumar Swarnkar
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Friends,
Need to know if a class (say class A) has two 'synchronized' methods, then is it possible to access each of these 'synchronized' methods by two separate object(say instance of class B and class C) ?

As per theory in java:
Every Class has a Lock.
Every Instance has a Lock.
Every Object has a Lock. (am not sure about the instance lock and object lock; whether they are same or different !? ).

Anyway, does this theory mean:

to work on any synchronize method an object need to acquire the lock of class(?) OR object/instance(?).
Can anybody please elaborate it.


thanks in advance !!
[ June 22, 2008: Message edited by: Ramesh Kumar Swarnkar ]
 
Charles Lyons
Author
Ranch Hand
Posts: 836
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If the synchronized method is a static method, a class lock is used (since the method is assumed to act the same for all instances).

Synchronizing an instance method uses the object's lock, since we assume we're modifying the state of a specific object - and each object is separate from every other of the same class. E.g. suppose you have a banking application with a class Account which stores a balance for a particular customer. Then you would only want to lock one customer's Account when doing an update on their account balance - locking everyone's accounts would be daft since using instance methods means only the one Account object is affected by assumption (if for some reason this isn't true, you'd need to look at using synchronized blocks on some other object instead).

See also: Class locks & non-static methods
 
Ramesh Kumar Swarnkar
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Charles,
From your post, I can understand the use of 'Static' and 'non-static' synchronize. Or the practical use of 'Class Lock' and 'Object Lock'.
Thank you for such a simple and good example.

SO, If I try to relate this to my very first question:
if a class (say class A) has two non-static 'synchronized' methods, then is it possible to access each of these 'synchronized' methods by two different object(say instance of class B and instance of class C) SIMULATANEOUSLY ?

= reply would be, YES (please correct me if I interpret your reply wrongly).

Moreover,
1. the instance of Class B and C can even work SIMULTANEOUSLY on 'non-static' Synchronize method of class A as these two instances(objects) will have their own states; and they have separate 'Object Locks'.

2. But, if I declare the method of class A as 'static synchronise', then two separate objects B and C can not act simulateneously because of Class lock.

Charles, please correct me.


regards,
Ramesh
[ June 22, 2008: Message edited by: Ramesh Kumar Swarnkar ]
 
Charles Lyons
Author
Ranch Hand
Posts: 836
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
if a class (say class A) has two non-static 'synchronized' methods, then is it possible to access each of these 'synchronized' methods by two different object(say instance of class B and instance of class C) SIMULATANEOUSLY ?
Remember what we're talking about is multi-threading. It doesn't matter in which objects we do the invoking of methods, but which threads all those objects are executing in when the invocation is done (and since execution in a single thread is sequential, we cannot invoke the same method twice simultaneously in a single thread, unless we're using recursion).

I think it's easiest to work through this with a simple example. Let's take one class with one synchronized instance method:and also declare a couple of instances of this class I1 and I2 say. We also have three threads around and running - let's call them T1, T2 and T3.

Now, suppose within thread T1 we invoke I1.mymethod() at some point in time. Then until this invocation returns, T2 and T3 are locked out of calling I1.mymethod(). However, one of those threads may still invoke I2.mymethod() without blocking since that's a different object (albeit of the same class). Once I1.mymethod() returns, any of the threads may again invoke that method on that object. Similarly, once I2.mymethod() returns, any of the threads may invoke that method.

I think you may have understood, but it was unclear when you were referring to different classes instead of instances of the same class. Your example was correct: if we have several different classes, then we can apply the same logic as above if I1 is an instance of ClassA, I2 of ClassB and a third instance I3 of ClassC, but it's probably less obvious to consider the case where they are all of the same class first.

Now, if we make the method static:then the previous explanation will fail since the lock is now a class lock so holds on all static methods of all instances of ClassA simultaneously. An invocation of I1.mymethod() from thread T1 will now lock threads T2 and T3 from calling any occurrences of any static methods on any other instances of ClassA. However, since it's a class lock, it won't block any invocations of static methods from other classes (i.e. classes other than ClassA), nor will it block invocations of instance methods.

Does that help? If you want to write some examples to help clarify, that might be worthwhile.
[ June 22, 2008: Message edited by: Charles Lyons ]
 
Ramesh Kumar Swarnkar
Ranch Hand
Posts: 84
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Charles,
Thank you for further clarification.I think I got more clear concepts.
But, while talking about the word static synchronized, one more question/clue hits my mind. I think I must put that here.

The discussion we have come across from our above posts, are JVM specific. I mean, these scenarios we are talking are for One JVM.

So,please help me to know, how to maintain a 'class Lock' across multiple JVM(s) ? Meaning to say, can I make a method which is 'static synchronize' in a class and already in execution in one JVM, can not be invoked in any other JVM, unless the execution is over in first JVM ?

Let me make my question more clear by adding this code :

while running this sample code, I can see the System.out.print("hi") in both the JVM(s) running concurrently. Which I do not want. I want the other JVM to wait unless the operation is over in first JVM.
Please suggest.

thanks in advance,
regards,
Ramesh
 
Charles Lyons
Author
Ranch Hand
Posts: 836
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The discussion we have come across from our above posts, are JVM specific. I mean, these scenarios we are talking are for One JVM.

So,please help me to know, how to maintain a 'class Lock' across multiple JVM(s)?
No that's not possible. Separate JVMs running don't talk to each other unless you have programmed them explicitly to via sockets, filesystem etc. This is because they occupy totally separate segments of memory (execution space) and so don't share anything other than possibly the common runtime libraries - though they use different class loaders so have different instances of all the objects. Recall, you also can't share objects between JVMs without some clever code.

If for some reason you need to use synchronization between two Java programs, you need to seek some other way of communicating between the two programs. Probably the easiest thing to do is use a file lock on the hard drive. Put simply, this says that if a file is in a certain state on the hard drive, no other JVMs can move past the block of code and should wait until that file has moved out of the state. As a simple example:
  • JVM 1 creates file mylock.txt and enters a block of code
  • JVM 2 sees the file already exists so waits
  • JVM 1 exits the block of code and deletes the file mylock.txt
  • JVM 2 sees the file doesn't exist so creates it and enters the block of code etc.
  • That's a very simple but not practical idea. A better way would be to look at the java.nio.channels.FileChannel's lock() method which will block until the lock is available. So in your example write:This will now synchronize between multiple JVMs, however according to the API, "File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine." Therefore you'd need to also think about how to control access within the same JVM, using synchronized keyword perhaps?
    [ June 23, 2008: Message edited by: Charles Lyons ]
     
    Paul Sisco
    Greenhorn
    Posts: 11
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Ramesh Kumar Swarnkar:
    Hi Friends,
    Need to know if a class (say class A) has two 'synchronized' methods, then is it possible to access each of these 'synchronized' methods by two separate object(say instance of class B and class C) ?

    As per theory in java:
    Every Class has a Lock.
    Every Instance has a Lock.
    Every Object has a Lock. (am not sure about the instance lock and object lock; whether they are same or different !? ).

    Anyway, does this theory mean:

    to work on any synchronize method an object need to acquire the lock of class(?) OR object/instance(?).
    Can anybody please elaborate it.


    thanks in advance !!

    [ June 22, 2008: Message edited by: Ramesh Kumar Swarnkar ]


    Just to add my two cents....

    Please let me know if I did not understand the question completely.

    I took this to mean that you wanted to call the different methods on the same instance of a class. If the methods are synchronized, they are synchronized on the class, and the will not run at the same time. If you use a synchronized block within the methods, they will run at the same time.

    If I make a small class like this:

    Then I made a couple of threads to call the same instance of the above class 1000 times each. Thread 1 called method 1, and thread 2 called method 2.
    This is a sample of the output:
    Method 2 Start: 1214250298180
    Method 1 Start: 1214250298180
    Method 2 End: 1214250298273
    Method 2 Start: 1214250298273
    Method 1 End: 1214250298273
    Method 1 Start: 1214250298273
    Method 2 End: 1214250298367

    Notice that the start and end lines overlap. If the methods are synchronized, each method call would need to end before the other one could begin.
    [ June 23, 2008: Message edited by: Paul Sisco ]
     
    Ramesh Kumar Swarnkar
    Ranch Hand
    Posts: 84
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Paul,


    I took this to mean that you wanted to call the different methods on the same instance of a class. If the methods are synchronized, they are synchronized on the class, and the will not run at the same time. If you use a synchronized block within the methods, they will run at the same time.

    = No.
    Sorry, if my question gives that impression.May be would have been more specific.

    But, from above posts I come to a conclusion that:
    if a method is 'static-synchronized', then to work on this method, one has to acquire Class Lock.

    But, if the method is 'synchronized', then to work this method, one has to acquire Object Lock. And this implies to 'synchronized block' also.
     
    Paul Sisco
    Greenhorn
    Posts: 11
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Ramesh Kumar Swarnkar:
    Hi Paul,


    = No.
    Sorry, if my question gives that impression.May be would have been more specific.

    But, from above posts I come to a conclusion that:
    if a method is 'static-synchronized', then to work on this method, one has to acquire Class Lock.



    But, if the method is 'synchronized', then to work this method, one has to acquire Object Lock. And this implies to 'synchronized block' also.


    That is right. Using the sinchronized(){} block will synchronize on the object passed in, and it is just a way to have multiple locks at at the same time, within the same object. I have found it usefull for session objects that can be called my more than one other object at the same time.
    Sinchronized methods are probably cleaner. Keeping it simple is good.
     
    marlajee Borstone
    Ranch Hand
    Posts: 35
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    So, say if I have a class A, such that


    In some another class, say:


    Now, my question is, whether these Two threads T1 and T2 will be able to access the 'doSomething()' method of class A from these two separate Threads Simultaneously ?
    = AS per understanding it is possible to access the 'doSomething()' method from two separate threads T1 and T2, because T1 and T2 has separate objects aa and bb respectively.Please correct me if I am wrong somewhere !!!

    waiting for remark ....

    Dhaansumaal.
    [ July 26, 2008: Message edited by: marlajee Borstone ]
     
    Ernest Friedman-Hill
    author and iconoclast
    Sheriff
    Posts: 24215
    37
    Chrome Eclipse IDE Mac OS X
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by marlajee Borstone:
    Please correct me if I am wrong somewhere !!!


    You are correct. A synchronized instance method can be called by two threads simultaneously on two separate instances.
     
    marlajee Borstone
    Ranch Hand
    Posts: 35
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks Ernest Friedman-Hill !!

    regards,
    Dhaansumaal.
     
    marlajee Borstone
    Ranch Hand
    Posts: 35
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Need to have an practicle example for static synchronize. For that I have two question :
    1.)
    If I mark this method as static synchronize, such that :



    Now, this class is being accessed from some third class 'ThirdClass', such that :



    Now, my question is, whether these Two threads T1 and T2 will be able to access the 'doSomething()' method of class A from these two separate Threads Simultaneously ?

    2.) Same question is if I use the same instance to access from two separate Thread T1 and T2, will they be able to access the 'doSomethig()' simulatenously ?



    Please help me.


    waiting for remark ....

    Dhaansumaal.
     
    Savita Sharma
    Greenhorn
    Posts: 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi,

    Thanks for your very informative post on Synchronization.I know that in Struts 1 only one instance of Action class is created.Now my confusion is that if i create new instance of my DAO in Action class execute method and then call some method on the DAO (eg dao.generateLicenceNumber())inside execute , do i face issues with synchronization.i want to generate unique License# for each user request.So do i need to make generateLienseNumber() method static synchronized so that no two users can access that method simultaneously.

    sample code is like:
    public class someClass extends Action
    {
    execute(){
    DAO dao = new DAO();
    int licNum = dao.generateLicenseNumber();
    }
    }

    class DAO{
    int generateLicenseNumber(){
    //some logic
    }

    }
     
    Savita Sharma
    Greenhorn
    Posts: 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Sorry about that.I have updated it.
     
    It is sorta covered in the JavaRanch Style Guide.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!