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


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Reg. Some Thread basics" Watch "Reg. Some Thread basics" New topic
Author

Reg. Some Thread basics

Angela Narain
Ranch Hand

Joined: Apr 14, 2001
Posts: 327

I am not clear on how thread share objects.
Below is what i understand :
Case 1:
As per lines //1 and //2 two threads are created
independent of each other, not sharing any object.
Case 2:
As per lines //3 and //4 two threads are created
which are sharing the "Mythread" object.
So when one thread is working inside run() another
thread cannot invoke a method on the same object

So only after one thread finishes with the run() call,
the next thread can start.
Case 3:
As per lines //5 and //6 two threads are created.
The second thread created in line //6 creates a new
instance of MyThread . So is it still shared between
the two thread?
The output in both the Case 2 and Case 3. are same.
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Angela first, you should put the line which prints "Inside Run" inside the synchronized block too (or make the run method synchronized). Then you cannot say that the output is the same for the second and the third case because it may not be so on another platform. AS IS the code could well output
Inside Run
Inside Run
Inside Synchronized
Inside Synchronized
since nothing prevent two threads to enter the run method one after another (one of them will just be blocked when attempting to enter the syunchronized block).
In cases 1 and 2, the Thread are sharing the same run method but not in case 3 since they have different targets, one is an instance t of MyThread and the other is another new instance of MyThread, so the run method is not shared...
HIH

------------------
Valentin Crettaz
Sun Certified Programmer for Java 2 Platform


SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML
[Blog] [Blogroll] [My Reviews] My Linked In
Angela Narain
Ranch Hand

Joined: Apr 14, 2001
Posts: 327
Thanks Val,
Can you give me some simple example to understand synchronization
between threads when there are more than one synchronized
methods.
Angela Narain
Ranch Hand

Joined: Apr 14, 2001
Posts: 327
I just tried out the below code :

Why is the get() method executed after set() ?
I am not using any synchronization over here.
But always i am getting the output as :
Inside run
Inside set
Inside get
Inside run
Inside set
Inside get
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Hi Angela
the get() incovation is after the set() invocation so I think that's normal that get will be called after set. But again it depends on the platform you are running. Since you have two Thread sharing the same run method the output could well be any of the following:
1.
Inside run //thread 1
Inside run //thread 2
Inside set //thread 1
Inside set //thread 2
Inside get //thread 1
Inside get //thread 2
2.
Inside run //thread 1
Inside set //thread 1
Inside get //thread 1
Inside run //thread 2
Inside set //thread 2
Inside get //thread 2
3.
Inside run //thread 1
Inside set //thread 1
Inside run //thread 2
Inside set //thread 2
Inside get //thread 2
Inside get //thread 1
4.
Inside run //thread 1
Inside run //thread 2
Inside set //thread 1
Inside get //thread 1
Inside set //thread 2
Inside get //thread 2
and many other schemes too but I hope you get the meaning of this...
summing up, the set and get will always be called one after another respective to one thread which means that if we look at the first thread the get will not be invoked unless the set has been invoked before (sequentiality !)
HIH
------------------
Valentin Crettaz
Sun Certified Programmer for Java 2 Platform
[This message has been edited by Valentin Crettaz (edited October 04, 2001).]
Ragu Sivaraman
Ranch Hand

Joined: Jul 20, 2001
Posts: 464
Originally posted by Valentin Crettaz:
Angela first, you should put the line which prints "Inside Run" inside the synchronized block too (or make the run method synchronized). Then you cannot say that the output is the same for the second and the third case because it may not be so on another platform. AS IS the code could well output
Inside Run
Inside Run
Inside Synchronized
Inside Synchronized
since nothing prevent two threads to enter the run method one after another (one of them will just be blocked when attempting to enter the syunchronized block).
In cases 1 and 2, the Thread are sharing the same run method but not in case 3 since they have different targets, one is an instance t of MyThread and the other is another new instance of MyThread, so the run method is not shared...
HIH

Val and Angela...
Case 1:
Both of the threads share the same run().
Therefore, the synchronized code functions
(ie block/notify)
Proof: Output
Case 2:
MyThread t = new MyThread();
new Thread(t).start();
new Thread(t).start();
Two SEPERATE Threads are spawned.
Of course they have the same target.
But they are not contenting each other for the object lock...
How?
Its becoz of this stmt... synchronized(this).....
"this"... in this case refers to "new Thread"
Therefore, each Thread gets to run its run() method completely
without any interruption (ie block aka wait/notify)
Proof: Output
3. Case 3:
Val explanation is very sufficient . I just to re-iterate that
again they are two different Threads spawned and have no correlation or communication between each other
These are the reasons i believe as why the case 2 and 3 produce the same results
Thankyou
Ragu
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610

Output
Inside run class MyThread
Inside synchronized
Inside run class MyThread
Inside synchronized

I don't really agree with you, the target is the same and thus the run method executed by both Threads are also the same run method !! "this" refers to the MyThread instance and not to the Thread since the run is a member method of MyThread class and not Thread class (in this case) !
Let me know
------------------
Valentin Crettaz
Sun Certified Programmer for Java 2 Platform
[This message has been edited by Valentin Crettaz (edited October 04, 2001).]
Ragu Sivaraman
Ranch Hand

Joined: Jul 20, 2001
Posts: 464
Wow!! these Threads are always weird
If i run same code given by angela
i get
C:\SCJP>java MyThread
Inside run
Inside synchronized
Inside run
Inside synchronized
C:\SCJP>java MyThread
Inside run
Inside synchronized
Inside run
Inside synchronized
C:\SCJP>java MyThread
Inside run
Inside synchronized
Inside run
Inside synchronized
All the 3 cases the same output!!!
Win 98/JDK 1.3 build 1.3.0-C
So the outputs are OS dependent?

Val you are correct in your judgement . I stand corrected

But can someone clarify this for me please?
Valentin Crettaz
Gold Digger
Sheriff

Joined: Aug 26, 2001
Posts: 7610
Yes the output is OS dependent, in fact if you don't use synchronized blocks then you can't say anything about the output.

------------------
Valentin Crettaz
Sun Certified Programmer for Java 2 Platform
[This message has been edited by Valentin Crettaz (edited October 04, 2001).]
Angela Narain
Ranch Hand

Joined: Apr 14, 2001
Posts: 327
I am still not clear ..
Consider same example with some more print statements :

OUTPUT :
Inside run Thread[Thread-0,5,main]
Value of this Thread[Thread-0,5,main]
Inside synchronized

Inside run Thread[Thread-1,5,main]
Value of this Thread[Thread-1,5,main]
Inside synchronized
Both the threads are created using "new". So i suppose
that "this" instance is not the same for both of them
as i have printed both the values.
How does synchronization work in this case ??
I am clear that when we do something like below

MyThread1 t = new MyThread1();
new Thread(t).start(); //1
new Thread(t).start(); //2

The MyThread object "t" is shared among both the threads.
So only one thread at a time will execute the run method.

Gagan Indus
Ranch Hand

Joined: Feb 28, 2001
Posts: 346
Angela
u seems as confused as i was , when i touched this interesting topic ..lol
well.. may seem like bit weird way to go ,
but lets stress on following points first , n then get on wid our prob ...
1) Every Object has a lock , so any Object can be monitor . ( talking of instance lock , forget class-wide lock for a while )
2) Object contaning synchronized methods , and Threads calling these methods , are different entities.( of course )
( If the Object is a instance of Thread/subclass of Thread , even then safely think of them as diff entities , coz they r diff)
3) Blocks synchronized on this object-reference, and synchronized methods share da same instance lock .
( like saying

public void run()
{
synchronized(this)
{
//do losta work
}
}

and

synchronized public void run()
{
//do losta work
}

is one n da same thing( as long as there is no statement outside da sync block ! )
)
4) Synchronized methods/blocks guarantee tht "When one Thread is executing code between these blocks , NO other thread will be allowed to enter these blocks " . Or in other words , Whenever a thread tries to execute a synchronized block it shd FIRST obtain
the mutually exclusive lock of Object.
5) Very basic thing, For any given synchronized/non-synchronized block , oreder of execution is sequential ( as for Angela's other code , if set()'s called bfore get() , then dats da order in which they be executed )
okay lets get going wid ur example :
Two differnet Objects of class Thread1 are made in main method , they get name Thread-0 and Thread-1 by default , as we havent provided name explicitly.
Some part of run() method is synchronized ,as Both Objects are DIFF , so locks of these are ALSO DIFF .
So , when JVM spawn 2 new Threads on call to start() method of each Objects ( remember our promise , we will think Objects n Threads to be diff entities ? ) , and when one of these newly-spawn Thread calls run() and is executing synchronized-portion of its corresponding-run()( wid its coreesponding Object-lock ) , The other Thread can simultaneously run the synchronized-portion of it's corrsponding run() ( Coz it's Object-lock is entirely diff, so no prob)
Okay , lemme try a lill more !
Lets name the two Objects made in main methods as :
OBJ0 & OBJ1
Both of these are having individual locks , lets call them as :
LOCK_OF_OBJ0 & LOCK_OF_OBJ1
When , start method of these objects is called , JVM spawns a new Thread for each , lets call them :
THREAD-0 & THREAD-1
Suppose THREAD-0 gets to run first , now when THREAD-0 reaches the synchronized statement synchronized(this) , it obtains the LOCK_OF_OBJ0 , and keep executing .
Assume that now THREAD-1 also gets its turn to run .And it reaches the statement synchronized(this) , while THREAD-0 is still inside sync-block . There wont be any problem , as THRED-1 is required to obtain LOCK_OF_OBJ1 (and not LOCK_OF_OBJ0 ) , so THREAD1 will also go-ahead wid executing da code in sync-block.

Other points in synchronization , which may help :
- when synchronized method/block of a Object is running , non-synchronized code of same Object can always be run simultaneously , coz it don require lock.
- Class-wide lock r diff from instance-locks , synchronized methods use class-wide locks.
- Blocks can be synchronized , on any Object , like sunchronized(Object) . But synchronized(this) is most frequently used case.


------------------
Gagan (/^_^\) SCJP2
Die-hard JavaMonk -- little Java a day , keeps u going .


Gagan (/^_^\) SCJP2 SCWCD IBM486 <br />Die-hard JavaMonk -- little Java a day, keeps you going.<br /><a href="http://www.objectfirst.com/blog" target="_blank" rel="nofollow">My Blog</a>
Angela Narain
Ranch Hand

Joined: Apr 14, 2001
Posts: 327
1. What if there is some code outside the synchronized() code block ?
For eg ;
public void run() {
System.out.println("1");
synchronized(this){
System.out.println(" Inside syncrhonized");
}
}
>> I suppose that portion will not be synchronized.
==================================================

2. With respect to your 3) point

3) Blocks synchronized on this object-reference, and synchronized methods share da same instance lock .
( like saying
public void run()
{
synchronized(this)
{
//do losta work
}
}
and
synchronized public void run()
{
//do losta work
}
is one n da same thing( as long as there is no statement outside da sync block ! )
)

For eg :
am here assuming that making the method run() as synchronized or putting
the synchronized(this) with no statements outside is same


The output can be of any order something like this
OUTPUT 1:

1
Only Thread[Thread-0,5,main] 1
In synchronized
Only Thread[Thread-1,5,main] In synchronized

OR
OUTPUT 2:

1
Only Thread[Thread-0,5,main] In synchronized
1
Only Thread[Thread-1,5,main] In synchronized

I get the almost similar results as above if i try to remove synchronized(this)
and make the run() method synchronized.

Now suppose i want to get the sequence strictly as OUTPUT 2:
i do something as below , that is share the object between
the threads :
i change the main method as
MyThread1 t = new MyThread1();
new Thread().start(); //1
new Thread().start(); //2
Pls. correct if wrong
Angela Narain
Ranch Hand

Joined: Apr 14, 2001
Posts: 327
Some more doubts :

Consider the following :

and the following instantiations :
Object obj1 = new Object();
Object obj2 = new Object();
Assume that the first thread calls the method getLocks(obj1, obj2).
What should the second thread call.
ans: It should call getLocks(obj1,obj2)
Okay i got to some point that calling getLocks(obj2,obj1)
will cause a deadlock condition.
But can someone explain me in very simple terms, step-by-step
as to how first thread will execute the method getLocks()
and then how the second thread proceeds ...
Thanks in advance.
Gagan Indus
Ranch Hand

Joined: Feb 28, 2001
Posts: 346

1. What if there is some code outside the synchronized() code block ?

You are 100% correct , Angela , that code WONT be synchronized . Threads WONT need to obtain any lock to run such code.


Now suppose i want to get the sequence strictly as OUTPUT 2:
i do something as below , that is share the object between
the threads :
i change the main method as
MyThread1 t = new MyThread1();
new Thread().start(); //1
new Thread().start(); //2
Pls. correct if wrong

NO , Angela , no sharing of Objects is being done ! . The Objects being made at line#1 and line#2 are entirely diff !
I guess , u instead meant this :
MyThread1 t = new MyThread1();
new Thread(t).start(); //1
new Thread(t).start(); //2
Right? .Okay , in this case , Runnable t is being shared b'ween Thread-Objects being made at Line#1 and Line#2 . There will be single lock of object t , which both Threads will be seeking for , so we will get the o/p same as OUTPUT2.
Coming to ur deadlock eg ; Here is my try to explain it in step-by-step procedure :
Again , start with the nomenclature, the two objects we gonna pass to methods , lets call them :
OBJ1 and OBJ2
and their corresponding locks as :
LOCK_OF_OBJ1 & LOCK_OF_OBJ2
The two Threads which will call methods , let then name as :
THREAD1 // it will call getLocks(obj1 , obj2)
THREAD2 // it will call getLocks(obj2 , obj1)
Lets also number code-lines of method getLocks() for reference :
1. public void getLocks( Object a, Object b) {
2. synchronized(a) {
3. synchronized(b) {
4. // do something
5. }
6. }
7. }
Finally , let us intialize the varibales obj1 & obj2 so as that
- reference obj1 points to object OBJ1 in heap ( obj1-->OBJ1)
- reference obj2 points to object OBJ2 in heap ( obj2-->OBJ2)
lets get going wid steps :
- THREAD1 calls getLocks(obj1 , obj2 ) .Values of reference varibles obj1, obj2 are copied to formal parameters a , b . so now
a-->OBJ1 and b-->OBJ2
- THREAD1 reaches line#2 , synchronized(a) , which now means synchronized(OBJ1) . So THREAD1 need to obtain LOCK_OF_OBJ1 , which it does ( for simplictiy assume only these Threads are contending for lock of OBJ1 n OBJ2)
- Now assume , THREAD2 gets its chance to run , it calls getLocks(obj2 , obj1 ). Values of reference varibles obj2, obj1 are copied to formal parameters a , b . so now
a-->OBJ2 and b-->OBJ1 ( NOTE DAT these a , b are diff from a,b in first step , coz formal parameters are made anew for every method call )
- THREAD2 reaches line#2 , synchronized(a) , which now means synchronized(OBJ2) . So THREAD2 need to obtain LOCK_OF_OBJ2 , which it does .
- Now , assume dat its again THREAD1 turn to run. THREAD1 reaches line#3 , synchronized(b) , which for it means synchronized(OBJ2) . So THREAD1 need to obtain LOCK_OF_OBJ2 , but this lock is with THREAD2 .
- THREAD2 gets its chance to run again , THREAD2 reaches line#3 , synchronized(b) , which for it means synchronized(OBJ1) . So THREAD2 need to obtain LOCK_OF_OBJ1 , but this lock is with THREAD1 .
- Hurrrraaaaahhhh !!! we have a deadlock !!!
THREAD1 seeks LOCK_OF_OBJ2 , which is wid THREAD2 , and THREAD2 seeks LOCK_OF_OBJ1 ,which is wid THREAD1.
( U like a gal , dat gal luvs another guy , dat guy got crush on second gal , who is more than interested in u ! . This is wht is real DEAD Lock ! lol , as at end of day some emotions hav to DIE!)

-------------------
Gagan (/^_^\) SCJP2
Die-hard JavaMonk -- little Java a day , keeps u going .
[This message has been edited by Gagan Indus (edited October 05, 2001).]
Angela Narain
Ranch Hand

Joined: Apr 14, 2001
Posts: 327
Thanks Gagan, It is getting bit clearer now.
I just tried the below code for testing synchronization
I am not getting the deadlock condition anytime.
May be something wrong with the code. Can you help me out.
Gagan Indus
Ranch Hand

Joined: Feb 28, 2001
Posts: 346
Yes Angela , code given by u will NOT lead to Deadlock.
First , Objects in reference-vars obj1 & obj2 are DIFFERENT for both MyThread instances . They should be SAME , as per our previous example , to cause deadlock . So declare these var-as static
Second , whether flag is true or false , run method calls getLocks(obj1 , obj2 ); . Change one of these calls to getLocks(obj2 , obj1 );
I hav done these changes in following code , and it is fully poiseed for a perfect-deadlock !


------------------
Gagan (/^_^\) SCJP2
Die-hard JavaMonk -- little Java a day , keeps u going .
Angela Narain
Ranch Hand

Joined: Apr 14, 2001
Posts: 327
Hi once again,
Does it depend upon the threading model of the system on which we run the program.
Bcoz i am not getting any deadlock condition !!!
So is it that "It may result in deadlock"
(FYI : system OS on which i am running is WinNT )
Another clarification i wanted was w.r.t to code as you explained.


Doubt 3:
IS there something like default priority of a thread ?
And What is the priority of the main thread?
When i create/spawn threads from the main thread and print their priority it print
5 which is the NORM_PRIORITY .
Thanks in advance
[This message has been edited by Angela Narain (edited October 06, 2001).]
Gagan Indus
Ranch Hand

Joined: Feb 28, 2001
Posts: 346

...Does it depend upon the threading model of the system on which we run the program....

Yes , Angela , it depends upon the threading-model in JVM , scheduling algorithm used , along wid no of threads running etc etc. (and also on ur LUCK , lol ,after all , u got to be lucky to get expected o/p from threads ! )
To clarify da reason for this , i 'll suggest u to look-again at the 6-steps for deadlock we discussed , in another eg. THREAD2 need to get its turn to run , when THREAD1 is holding LOCK_OF_OBJ1 . But based on the threading model , THREAD2 may only get its turn to run , only after THREAD1 fully completed . many other permutations , combinations possible , when 2/more threads r ruuning , only some specific order of execuation will lead to deadlock .
So " it MAY lead to deadlock " is the best suited statement .


...Another clarification i wanted was w.r.t to code as you explained...

Well , wot exact is bugging u in this code? Lemme knw , i can clarify code-submitted-by-me , and this new-code-subbmitted-by-u both , but first , lemme knw wht we shld discuss w.r.t these codes.

IS there something like default priority of a thread ?
And What is the priority of the main thread?
When i create/spawn threads from the main thread and print their priority it print
5 which is the NORM_PRIORITY .

Yes , there is a default priority of thread , its value is given by manifest constant , Thread.NORM_PRIORITY.
- If thread has a parent-thread , it gets same priority as parent-thread .
- Otherwise , it gets default-priority .
Priority of main-thread is default-priority , dat is to say , it is Thread.NORM_PRIORITY.

experiment this code :

its o/p is :
5
5
5
7
7
which shld clear any of ur doubts

------------------
Gagan (/^_^\) SCJP2
Die-hard JavaMonk -- little Java a day , keeps u going .
Angela Narain
Ranch Hand

Joined: Apr 14, 2001
Posts: 327
Sorry i missed out the clarifications that i wanted.
Here they are.
With reference to :
1. public void getLocks( Object a, Object b) {
2. synchronized(a) {
3. synchronized(b) {
4. // do something
5. }
6. }
7. }
Doubt 1:
I am not clear that what exactly happens after the first thread has called the
getLocks method i.e thread1.getLocks(obj1, obj2)
Specifically after executing the synchronized(obj1) ( line 2.) , the thread1 acquires the lock on object1.
What does the thread1 do with the line 3. ? Does it keep waiting to get the lock on object 2.
In general, when one thread say thread1 has acquired the lock on one object say obj1.
Does it wait for getting the lock on another object say obj2?
Doubt 2:
What happen when we declare the objects as static.
What i understand is that it will remain same for all instances of the class.
So in sort will be shared across the instances of the class leading to
proper synchronization.
Gagan Indus
Ranch Hand

Joined: Feb 28, 2001
Posts: 346
Reg. Doubt1 :
When , THREAD1 obtains LOCK_OF_OBJ1 , it is ready to run the code between synchronized(a) {...} block and need NOT to wait ( The line which makes it to obtain another lock is synchronized(b) , which is the very next line )
In those 6 steps leading to deadlock , we had have some assumptions :
( read those steps again and note tht step3 n step5 starts wid "Now assume.." )
- Just after the THREAD1 acquires LOCK_OF_OBJ1 , the JVM-scheduling algorithm moves it to ready-to-run state , as it decides that now is the turn of THREAD2 to execute ( This switching of Threads has nuting to do wid the fact tht it just acquired some lock , its JVM-scheduler's decision )
- Simlilarly , we again assume , dat Just after the THREAD2 acquires LOCK_OF_OBJ2 , the JVM-scheduling algorithm moves it to ready-to-run state , as it decides that now is again the turn of THREAD1 to execute.

So In general , any Thread NEED-NOT to wait and get outta running state , when it jus acqired some lock , It can execute statements widin dat sync-blocks , which may instruct it to obtain another lock ( as statements b'ween sync-block can be another sync-statement ) , which it keeps on doin until it is able to .
( Such Thread only waits , and moves to waiting-state , in da condition , in which da-lock it is looking 4 is wid some another Thread . This is precialy wot happens at step5 n step6 )

Reg. Doubt2 :
Yes , your understanding is perfectly fine .


------------------
Gagan (/^_^\) SCJP2
Die-hard JavaMonk -- little Java a day , keeps u going .
Shanel Jacob
Ranch Hand

Joined: Jun 18, 2006
Posts: 112
Based on the reply/comment below:

Originally posted by Gagan Indus:
Angela

3) Blocks synchronized on this object-reference, and synchronized methods share da same instance lock .
( like saying
<font color="red">
public void run()
{
synchronized(this)
{
//do losta work
}
}
</font>
and
<font color="red">
synchronized public void run()
{
//do losta work
}
</font>
is one n da same thing( as long as there is no statement outside da sync block ! )
)


That means the only way we can synchronize 2 different threads is to use:



Is this correct? The question above is quite similar to the mock question from JQ+ which really confuses me: http://www.coderanch.com/t/225825/java-programmer-SCJP/certification/Reg-Some-Thread-basics

So if you want to synchronize 2 threads AND ensure that "x" and "y" are always equal. You need to "synchronized (MyThread1.class)" because "synchronized(this)" or "synchronized public void run()" is redundant therefore not going to do the work.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Reg. Some Thread basics
 
Similar Threads
Threads
Question on syncrhonized methods
synchronized - join
begin execution of a thread -- start or run?
Synchronized block in run() method itself