Author Topic:   Synchronized block
javaBiginner
unregistered
posted March 30, 2000 11:44 AM           
In Marcus' tuitorial, it said:
When a synchronized block is executed, it's object is locked and it cannot be called by any other code until the lock is freeed.

Here, we know for sure that the synchronized block can't be called. But how about the unsynchronized methods? Can any other code call the unsync methods whild the sync block is called?

Jim Yingst
sheriff
posted March 30, 2000 12:38 PM             
Yup, absolutely. If this is a problem, make sure the data can only be accessed through synchronized methods.

Paul Keohan
greenhorn
posted March 30, 2000 06:14 PM             
This confuses me. If one method out of three is synchronized, why do we say the object is locked? I would say just that method's data is locked.

maha anna
bartender
posted March 31, 2000 09:48 AM             
Paul,
I tried to answer. Please read the foll. I also handgrafted an example program (after scratched my head a lot ). Participate in this discussion. I post the concept in this post and the Example program in
the very next post so that it doesn't look too long at first.
regds
maha anna
Obtaining lock on an object
---------------------------

- Each object has an associated lock with it.
- This lock is useful ONLY for executing SYNCHRONIZED INSTANCE METHODS as foll.
class MyClass {
synchronized void instSyncMethod1() {}
synchronized void instSyncMethod2() {}
void ordinaryMethod() {}
}
- Whenever a thread tries to execute a synchronized block it shd FIRST obtain
this mutually exclusive lock. I am saying MUTUALLY EXCLUSIVE here meaning,
at any point of time ONLY ONE thread can have this lock associated with this
object.
- So assuming, Thread1 obtains the lock for an object (object1) of this "Myclass"
class and starts executing the code inside the instSyncMethod1(). So now the
lock is with Thread1

Scenario - 1
-------------

- Assume now a TimeSharing Thread Scheduler, stops this Thread1 and schedules
another Thread2.
- Assume Thread2 uses this SAME object and tries to execute synchronized
instSuncMethod2().
- It WILL fail, because the lock is NOT YET free. It is still with Thread1.
SO Thread2 goes back to waiting for lock pool of this Object.

Scenario - 2
-------------
- Instead of the above case, if Thread2 WOULD HAVE tried to execute the
ordinaryMethod() of the SAME OBJECT whose locks is currently helf by
Thread1.
- It WILL SURELY BE successful. Because in order to execute this
ordinaryMethod() , no lock is necessary.

Scenario - 3
-------------

- Instead pf Scenario 2, if Thread2 which WOULD HAVE used ANOTHER OBJECT
OF THE SAME CLASS (object2), can still access ANY OF instSyncMethod1(),
instSyncMethod2(), ordinaryMethod()
- Because this object2 is completely another NEW object and it has its OWN
lock which is used by Thread2

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() {}

}
- This staticSyncMethod1() obtains the lock associated with the Class object
for this Myclass as a whole. It is same as the foll
synchronized (Class.forName("MyClass")) {
}
- Assuming Thread1 calls this staticSyncMethod() on object1, then NO OTHER
THREAD can access ANY METHOD on ANY OTHER OBJECT including the object used
by Thread1, UNTIL this Thread1 releases this Class lock.
- This means NO OTHER Thread can call any of the methods in this object,
or any method on any other NEW objects of this SAME class.
****************************************************************

[This message has been edited by maha anna (edited March 31, 2000).]

maha anna
bartender
posted March 31, 2000 09:50 AM             
Here comes the example program.

class PrintUpto5 {
static synchronized void staticSyncPrint(){
for(int i=0; i<5; i++) {
System.out.println("i= "+i+Thread.currentThread().getName()+" " + "Static Sysnc print ");
}
}

synchronized void syncPrint(){
for(int i=0; i<5; i++) {
System.out.println("i= "+i+Thread.currentThread().getName()+" " + "Sysnc print ");
}
}
void nonSyncPrint(){
for(int k=0; k<5; k++) {
System.out.println("k= "+k+Thread.currentThread().getName()+" " + "Non Sysnc print ");
}
}
}

class ThreadCalling_Sync_Method extends Thread {
PrintUpto5 obj=null;
ThreadCalling_Sync_Method() {
super();
}
ThreadCalling_Sync_Method(PrintUpto5 obj) {
this.obj = obj;
}
public void run() {
this.obj.syncPrint();//Call the Synchronized Method
}
}

class ThreadCalling_StaticSync_Method extends Thread{
PrintUpto5 obj=null;

ThreadCalling_StaticSync_Method() {
super();
}
ThreadCalling_StaticSync_Method(PrintUpto5 obj) {
this.obj = obj;
}
public void run() {
this.obj.staticSyncPrint();//Call the staticSynchronized Method
}
}

class ThreadCalling_NonSync_Method extends Thread{
PrintUpto5 obj=null;
ThreadCalling_NonSync_Method() {
super();
}
ThreadCalling_NonSync_Method(PrintUpto5 obj) {
this.obj = obj;
}
public void run() {
this.obj.nonSyncPrint(); //Call the Non-Synchronized Method
}
}

class Test {
public static void main(String[] args) throws Exception {

//Create the 2 objects of SAME class which will be bumbarded
//by the threads


PrintUpto5 printObj = new PrintUpto5();
PrintUpto5 printObj1 = new PrintUpto5();


//Scenario 1


/*ThreadCalling_Sync_Method t1 = new ThreadCalling_Sync_Method (printObj);
ThreadCalling_Sync_Method t2 = new ThreadCalling_Sync_Method (printObj);
t1.start();
t2.start();*/



/*-- output Scenario 1-------
i= 0Thread-0 Sysnc print
i= 1Thread-0 Sysnc print
i= 2Thread-0 Sysnc print
i= 3Thread-0 Sysnc print
i= 4Thread-0 Sysnc print
i= 0Thread-1 Sysnc print
i= 1Thread-1 Sysnc print
i= 2Thread-1 Sysnc print
i= 3Thread-1 Sysnc print
i= 4Thread-1 Sysnc print



Maha's comments : see here Thread 0 First finishes, then
releasing lock only, Thread-1 gets to execute, eventhough
it is executed in a timesharing scheduler like WIN98.


------------------------------*/


//Scenario 2

/*ThreadCalling_Sync_Method t1 = new ThreadCalling_Sync_Method (printObj);
ThreadCalling_NonSync_Method t2 = new ThreadCalling_NonSync_Method (printObj);
t1.start();
t2.start();*/

/*-- output Scenario 2-------
k= 0Thread-1 Non Sysnc print
k= 1Thread-1 Non Sysnc print
k= 2Thread-1 Non Sysnc print
i= 0Thread-0 Sysnc print
k= 3Thread-1 Non Sysnc print
i= 1Thread-0 Sysnc print
k= 4Thread-1 Non Sysnc print
i= 2Thread-0 Sysnc print
i= 3Thread-0 Sysnc print
i= 4Thread-0 Sysnc print


Maha's comments : see here , Thread2 has NO PRBLEM
in executing a non-sync method while Thread1 STILL
has the lock of the SAME object and not yet finished
it's run() method


------------------------------*/


//Scenario 3.1

/*ThreadCalling_Sync_Method t1 = new ThreadCalling_Sync_Method (printObj);
ThreadCalling_NonSync_Method t2 = new ThreadCalling_NonSync_Method (printObj1);
t1.start();
t2.start();*/


/*-- output Scenario 3.1-------
k= 0Thread-1 Non Sysnc print
i= 0Thread-0 Sysnc print
k= 1Thread-1 Non Sysnc print
i= 1Thread-0 Sysnc print
k= 2Thread-1 Non Sysnc print
i= 2Thread-0 Sysnc print
k= 3Thread-1 Non Sysnc print
i= 3Thread-0 Sysnc print
k= 4Thread-1 Non Sysnc print
i= 4Thread-0 Sysnc print

Maha's comments : see here. SAME as scenario 2
Thread2 has no problem in executing


------------------------------*/

//Scenario 3.2 another thread using another object calling Sync_method

/*ThreadCalling_Sync_Method t1 = new ThreadCalling_Sync_Method (printObj);
ThreadCalling_Sync_Method t2 = new ThreadCalling_Sync_Method (printObj1);
t1.start();
t2.start();*/

/*-- output Scenario 3.2
i= 0Thread-0 Sysnc print
i= 1Thread-0 Sysnc print
i= 2Thread-0 Sysnc print
i= 3Thread-0 Sysnc print
i= 0Thread-1 Sysnc print
i= 4Thread-0 Sysnc print
i= 1Thread-1 Sysnc print
i= 2Thread-1 Sysnc print
i= 3Thread-1 Sysnc print
i= 4Thread-1 Sysnc print

Maha's comments : see here. SAME as scenario 2
Thread2 has no problem in executing

------------------------------*/

//Scenario 4
ThreadCalling_StaticSync_Method t1 = new ThreadCalling_StaticSync_Method (printObj);
ThreadCalling_Sync_Method t2 = new ThreadCalling_Sync_Method (printObj1);
t1.start();
t2.start();

/*-- output Scenario 4
i= 0Thread-1 Sysnc print
i= 1Thread-1 Sysnc print
i= 0Thread-0 Static Sysnc print
i= 2Thread-1 Sysnc print
i= 1Thread-0 Static Sysnc print
i= 3Thread-1 Sysnc print
i= 2Thread-0 Static Sysnc print
i= 4Thread-1 Sysnc print
i= 3Thread-0 Static Sysnc print
i= 4Thread-0 Static Sysnc print
Maha's comments. This is NOT working properly.
Not consistant ,I do not know why....
Others can add to this.

------------------------------*/

}
}

[This message has been edited by maha anna (edited May 12, 2000).]

Sushma
greenhorn
posted May 11, 2000 10:02 AM             
Hi,
Maha Anna's explanation is very good.
But, what if Thread1 is executing one of the 3 methods of that object, and can Thread2 access the non sycronized method of that same object, i mean 'this' object???
Please explain this.
Regards,
Sushma

Herbert Maosa
greenhorn
posted May 11, 2000 11:28 AM             
Maha,

I clearly understand your explanations and it has helped clear off a lot of problems I had in percieving this. I however want to understand one more thing : When the synchronized method is static, does this mean that once one thread say Thread1 is executing in this method, then another thread can not execute even the non synchronized methods of this object ?

Thanks in advance.

maha anna
bartender
posted May 11, 2000 01:25 PM             
Sushma,Herbert,
You got the case I left out Herbert. Nothing restricts a thread executing a non_sync_method of any object of any class.. As you asked I included this case also. Here is the output.

Sushma,
The above explanation answers your qstn also. A non_sync method can be executed without any problem whether another thread holds the lock of this object/the Class lock of this object OR NOT.

regds
maha anna



maha's comments: See here. A Class level lock obtained by Thread 1. Still Thread 2
is able to execute the non_sync method of
another object of the SAME class.



ThreadCalling_Sync_Method t1 = new ThreadCalling_Sync_Method (printObj);
ThreadCalling_NonSync_Method t2 = new ThreadCalling_NonSync_Method (printObj1);
t1.start();
t2.start();


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


Sushma
greenhorn
posted May 12, 2000 12:18 PM             
Maha Anna,
Thanks you very much for ut detailed explanation.
I just want to summarize some facts about synchronization, can u pl look into this and lemme know if i'm correct??

i)Synchronized Methods::: A thread can access a non synchronized methods of an object even if some other thread has the lock on that object.

ii) Synchronized Blocks::: A thread can't access any data whether it be synchronized /non-synchronized methods of an object, if it doesn't have the lock of that object(since this object is locked as a whole).

iii) Synchronized static methods:: A thread can't access any data whether it be synchronized /non-synchronized methods of an object,and all the objects of that class if some other thread has the lock of this object thru the static synchronized method(since this class is locked as a whole).

Thanks a lot and looking forward for ur help...
Sushma

maha anna
bartender
posted May 12, 2000 01:29 PM             
Sushma, Take a cup of steaming coffee before going down

(i)Synchronized Methods::: A thread can access a non synchronized methods of an object even if some other thread has the lock on that object.

This statement is true. I presume , you are referring to synchronized instance methods here. This statement is ALSO true even static synchronized methods. As I said before nothing restricts a thread running a ordinary (non_sync) method whetehr that object's lock/object's Class is currently with someone else or not.

ii) Synchronized Blocks::: A thread can't access any data whether it be synchronized /non-synchronized methods of an object, if it doesn't have the lock of that object(since this object is locked as a whole).

This statement is not clearly worded. Hmmm.. A synchronized block means what? Like the foll. I have given the explanation as part od the code. I think you are missing this point. A synchronized block means it may be synchronized on the current object/any other object/you can obtain the lock of the Class of this current object / or in fact any Class level object. Go through the example below.



class Test {
//Note static/instance floating blocks can't be synchronized
/*
THis is not valid.
static synchronized { //static floating block }
synchronized { //instance floating block }
*/

void m1() {
synchronized(this ) {
// here you are obtaining the current object's (this)
//lock and proceeding. This means other threads can't
//execute the sync methods of this current object
//while they are free to run the ordinary (non-sync)
//methods. Got it

// Also note that any other thread can run any
// sync/non_sync method of ANOTHER object of the
// SAME class of this current object. Because here
// you are obtainig ONLY the one current object's lock
// NOT class LEVEL lock.


}
}
void m2() {
synchronized(someObjectRef) {
// here you are obtaining the some other
// object ref.d by someObjectRef and NOT the lock
//of the current object (this). Note the difference
//So other threads execute sync/non_sync methods
// of this current object(this).

//THis also means other threads can't
//access the sync method of the someObejctRef object
//since the lock is held here in this thread

// Here also any other thread can run any
// sync/non_sync method of ANOTHER object of the
// 'someOtherObjectRef's class .Because here
// you are obtainig ONLY the object level lock and
// NOT class LEVEL lock.


}
}

void m3() {
try {
synchronized(Class.forName("Test")) {
//Here you obtain the Class level lock of "Test"
// class and any other thread can't run any
// SYNC method on this object as well as any other
// object created under this class "Test" while
// they are free to run any ordinary method as I said
// before. Here instead of "Test" as arg you can
// give any class name and obtain the class level
// lock of that class
}
}catch(ClassNotFoundException e) {}
}


}

iii) Synchronized static methods:: A thread can't access any data whether it be

synchronized /non-synchronized methods of an object,and all the objects of that class if some other thread has the lock of this object thru the static synchronized method(since this class is locked as a whole).


Part of this is true. A thread is restricted to run the SYNCHRONIZED methods when the class level lock with some one else while it is free to run any ordinary method.

While understaning the lock concepts is important R&H also says in their book that class level locks are not covered by the SCJP2 exan

regds
maha anna

[This message has been edited by maha anna (edited May 12, 2000).]

Sushma
greenhorn
posted May 12, 2000 02:37 PM             
Thanks a lot maha Anna...
I think i got my concepts cleared.
Thanks a lot for ur patience ...
Sushma

|