aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes locking?? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "locking??" Watch "locking??" New topic
Author

locking??

Doit
Ranch Hand

Joined: Aug 03, 2000
Posts: 169
Hi,
Class A has two methods, one is normal method and the other
one is Synchronized method. A thread T has acquired lock
on a object obA of class A.
Can any other method of any object call the normal method of obA?
- Thanks
Marcela Blei
Ranch Hand

Joined: Jun 28, 2000
Posts: 477
The answer is: Yes
T acquieres a lock on obA by invoking the sychronized method, and no other thread can access any synchronized method of that instance.
But the methods which are not synchronized can be access without locking. Another doubt about this?
Doit
Ranch Hand

Joined: Aug 03, 2000
Posts: 169
That means the whole object is not locked. The Synchronized part is locked right?
maha anna
Ranch Hand

Joined: Jan 31, 2000
Posts: 1467
Doit,
PLese refer to the following discussion. Please come back if you want anything to discuss further.
regds
maha anna
Junaid Bhatra
Ranch Hand

Joined: Jun 27, 2000
Posts: 213
Maha,
I referred to your earlier post on this topic. Your explanation is excellent. However your explanation in scenario 4 is incorrect.

Scenario - 4
-------------
- Assuming there is another static synchronized method introduced in the
above class like this
class MyClass {
synchronized void instSyncMethod1() {}
synchronized void instSyncMethod2() {}
void ordinaryMethod() {}
static synchronized void staticSyncMethod1() {}
}

As far as I understand, class locks and object locks are entirely different entities. Suppose a thread THREAD1 obtains a class lock and is executing a static synchronized method, this does not prevent a thread THREAD2 from obtaining an object lock and executing a non-static synchronized method of the same class.
When you think of it, it does make sense, since you cannot acess instance variables from within a static method hence you cannot corrupt any data.
However the other way around is possible, i.e. you can access static variables from within an instance method. Thus when you access static variables from within a non-static synchronized method, you should also obtain a class lock to prevent data corruption (a thread can obtain both object lock as well as class lock at the same time).
class MyClass {
static Object staticVariable;
synchronized void instSyncMethod1() //obtain object lock
{
synchronized(staticVariable){ //obtain class lock too
//can access static variables in thread-safe manner now
}
}
}
maha anna
Ranch Hand

Joined: Jan 31, 2000
Posts: 1467
Junaid Bhatra,
Thank you for your analysis. Yes what you say is correct. I coded and tested what you said. The point which I missed was, 'If a thread objtains a class level lock, then another thread can very well be able to run ALL methods EXCEPT the 'static sync' methods
To test this I added 2 more Scenario 5 and /Scenario 5.1. Here is the output. I add the needed changes and the new cases 5, 5.1 to the above mentioned thread. Thank you Junaid.
There is a small correction to your post. It is NOT
synchronized(staticVariable){ //obtain class lock too
The argument to the sync block has to be either an objectRef (to obtain the object lock) OR Class.forName("SomeClassName") to obtain the 'class level lock'. We can't use a variableName.
regds
maha anna
<pre>

Scenario 5

</pre>
/* ThreadCalling_StaticSync_Method t1 = new ThreadCalling_StaticSync_Method (printObj);
ThreadCalling_StaticSync_Method t2 = new ThreadCalling_StaticSync_Method (printObj);
t1.start();
t2.start();*/

Maha's comments :
See here. 2 threads t1 and t2 obtaining the class level lock on same object. Since there is ONLY ONE class level lock for a class,once a thread objtains this 'class level lock', other threads HAVE TO wait for this 'class level lock' until the first thread has finished its work. In other words , once a 'static synchronized' method starts executing, other threads can't run another static sync method of ANY object of this class type.


i= 0Thread-0 Static Sysnc print
i= 1Thread-0 Static Sysnc print
i= 2Thread-0 Static Sysnc print
i= 3Thread-0 Static Sysnc print
i= 4Thread-0 Static Sysnc print
i= 0Thread-1 Static Sysnc print
i= 1Thread-1 Static Sysnc print
i= 2Thread-1 Static Sysnc print
i= 3Thread-1 Static Sysnc print
i= 4Thread-1 Static Sysnc print

<pre>

Scenario 5.1

</pre>
ThreadCalling_StaticSync_Method t1 = new ThreadCalling_StaticSync_Method (printObj);
ThreadCalling_StaticSync_Method t2 = new ThreadCalling_StaticSync_Method (printObj1);
t1.start();
t2.start();

Scenario 5.1 is an example for 2 threads t1 and t2, t1 obtaind the 'class level lock' from objec1, and thread t2 STILL UNABLE to run the 'static sync' method of ANOTHRE OBJECT of the same class.


i= 0Thread-0 Static Sysnc print
i= 1Thread-0 Static Sysnc print
i= 2Thread-0 Static Sysnc print
i= 3Thread-0 Static Sysnc print
i= 4Thread-0 Static Sysnc print
i= 0Thread-1 Static Sysnc print
i= 1Thread-1 Static Sysnc print
i= 2Thread-1 Static Sysnc print
i= 3Thread-1 Static Sysnc print
i= 4Thread-1 Static Sysnc print


[This message has been edited by maha anna (edited August 12, 2000).]
Junaid Bhatra
Ranch Hand

Joined: Jun 27, 2000
Posts: 213
Maha,
A class level lock can be obtained in 2 ways:
1)synchronized(Class.forName("MyClass")) OR
2)synchronized(staticVariable) where staticVariable is any static variable of the class.
The code snippet in my post above is correct and can successfully obtain a class-level lock.
I wrote a small test program to verify this:

This prints out:
thread1
thread1
thread1
thread1
thread1
thread2
thread2
thread2
thread2
thread2
Now if you change the code above to synchronized(this) instead of synchronized(staticVariable) i.e. obtain an object-lock instead of class-lock, it prints out:
thread1
thread2
thread1
thread2
thread1
thread2
thread1
thread2
thread1
thread2

[This message has been edited by Junaid Bhatra (edited August 13, 2000).]
maha anna
Ranch Hand

Joined: Jan 31, 2000
Posts: 1467
Oops!. I should have coded and tested. We can't capture the object level lock based on an instance variable isn't? I just presumed the concept to static variables also. I was wrong. Thanks for your code.
regds
maha anna
Vivek Shrivastava
Ranch Hand

Joined: Jun 03, 2000
Posts: 277
Hi bhatra and maha,
I need your help guys to undertsand something.
Scenario - 4
it is clear now ( not for me ) that a thread can obtain both object lock as well as class lock at the same time.
but i am little bit confuse.
as per example given by u guys it clear that a thread can obtain object lock even some other thread have class lock.
is it possible to have class lock for a thread at the same time when some other thread is having object lock first.
as per my resoaning it is not possible. because our instance methods can access static variables and statice methods can only access static variables. so it is possible that at some point both type of methods( static and instance) are trying to access the same variables ie we can have both lock at same time.
hope i am able to put my confusion here. (here we are talking about synchronized methods only)
vivek
[This message has been edited by Vivek Shrivastava (edited August 15, 2000).]
thomas
Ranch Hand

Joined: May 26, 2002
Posts: 79

A class level lock can be obtained in 2 ways:
1)synchronized(Class.forName("MyClass")) OR
2)synchronized(staticVariable) where staticVariable is any static variable of the class.

Junaid, I don't think the second point is true in general. You can synchronize on a static variable (or an instance variable) ONLY if the variable is pointing to an Object. In your example code, staticVariable IS pointing to an Object. So the code compiles and runs. But the lock you are securing is the lock on the Object that the variable is pointing to (NOT the lock on the class).
Right?
[This message has been edited by thomas (edited August 15, 2000).]
[This message has been edited by thomas (edited August 15, 2000).]
[This message has been edited by thomas (edited August 15, 2000).]
Marcela Blei
Ranch Hand

Joined: Jun 28, 2000
Posts: 477
I agree with thomas.
Could someone explain the following situation: You have an instance lock on an object, then another thread tries to lock that class but the instance object has the lock on the static synchronized method too, so it can�t get the lock in that scenario.
But if you have no instance or class locks on the class and you lock the class then any instance object could lock the class but cannot get lock on the static synchronized method, is that what you are trying to say? I don�t understant when a class lock could be usefull...
rajsim
Ranch Hand

Joined: May 31, 2000
Posts: 116
I agree with thomas.
In addition, class level lock could also be obtained by using ".class" as in
synchronized (test5.class) {
....
}
interestingly, you could also apply the ".class" to a primitive and use it like the following:
synchronized (int.class) {
....
}
beyond SCJP objectives, isn't it?
Marcela Blei
Ranch Hand

Joined: Jun 28, 2000
Posts: 477
Any light on my question?
maha anna
Ranch Hand

Joined: Jan 31, 2000
Posts: 1467
I also agree with Thomas. The lock actually got was not the 'class level lock' for Test5 class. It is the 'object level lock' for the object referenced by the variable 'staticVariable'. What really happened was when you call 2 threads calling that method, the first thred gets the object level lock on object ref.d by 'staticvariable' which is of type 'Object'. Now when another thread tries to acquire the same 'object level lock' on this object, since the 1st thread has it already, only when the first thread finishes its work with the object, the 2nd thread can get the 'object level lock'.
So is the output Thread0,Thread0, Thread0......then Thread1,Thread1....Thread1.
Also note that to make sure we can't get a lock on an variable which is not a object reference, when we change the above code as
static int StaticintVariable = 10;
and try to write
synchronized(StaticintVariable) {...} this code will not compile at all. We can obtain lock on a object reference variable only.
Vivek,
Each object has an object level lock of its own and a class-wide lock which is common for all the objects created from that ClassType. How this Thread concept works is, if a Thread first gets an object's objectLevelLock then another thread can't obtain the objectLevelLock until the first one releases it.
Simillarly, if a Thread acquires a class-wide lock on a ClassType then another thread can't obtain this class-wide lock until the first one finishes its work and releases the class-wide lock.
Also it is possible for a thread to obtain the objectLevelLock on an object while the class-wide lock for the object's ClassType is with another thread .
It is also possible for a thread to obtain the Class-wide lock for a Class type , while the someother thread has an objectlevelLock on an object created from this ClassType.
As you asked, how can we get the class-wide lock while the objectLevelLock is with another thread(instance synchronized method) can access and modify the static data, an object's instance method has access to the common static data, it can very well change it anytime, irrespective of another thread has the class-wide lock or not. Why to that extent? Even other non-synchronized static methods also can modify the static data right? Which means we have to write the code carefully. If you don't want the static data not to be modified at all, then write the code accordingly. Inside the code of other methods try to get the same class-wide lock like this. synchronized(ClassName.class) {....}. This avoids the others methods from corrupting the static data, while the classLevelLock is with some thread.
regds
maha anna
maha anna
Ranch Hand

Joined: Jan 31, 2000
Posts: 1467
Marcela Blei,
If I understand your post correctly, you are asking the case is like this.
case study 1:
------------
There is a thread t1, Classtype C1, object o1(of this classType),
and thred t1 got the objectLevelLock as well as classLevelLock, then another thread t2, can't get the classLevelLock but it can create another object o2 of this classType and objtain its objectLevelLock.
Yes it is true. I will think of the use of classLevelLock and post it latter.
regds
maha anna
Junaid Bhatra
Ranch Hand

Joined: Jun 27, 2000
Posts: 213
I agree with Thomas too.
If you synchronize on an instance (or static) variable and it isn't pointing to an object, it will throw a NullPointerException. And yes you cannot synchronize on primitives, only on object ref variables!
Ofcourse when you synchronize on a static variable, then you will obtain a class-level lock on the object to which the static variable is pointing to, and not the class-lock of the current class. This is analogous to synchronizing on an instance variable isn't it?
I guess my post conveyed a wrong impression that synchronized(staticVariable) would obtain a class-level lock on the current class. I never meant to say that. All I wanted to say was that Class.forName() is not the only way to obtain a class-level lock. Sorry for the confusion . And thanks thomas for pointing it out.
Rajsim --- Yes anyClass.class returns a Class object (just like Class.forName()). Definitely out of the SCJP objectives

[This message has been edited by Junaid Bhatra (edited August 15, 2000).]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: locking??