Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Question on Thread

 
Pallavi Chakraborty
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everybody,
This is a question from Khalid Mughal:
public static void main extends thread {
static Object lock1 = new Object();
static Object lock2 = new Object();
static volatile int i1,i2,j1,j2,k1,k2;
public void run(){while(true) {doit();check();}}
void doit(){
synchronized(lock1) {i1++ ;}
j1++;
synchronized(lock2) {k1++; k2++;}
j2++;
synchronized(lock1) {i2++ ;}
}
void check() {
if(i1 != i2) System.out.println("i");
if(j1 != j2) System.out.println("j");
if(k1 != k2) System.out.println("k");
}
public static void main(String args[]) {
new MyClass().start();
new MyClass().start();
}
}
The options are:
(a)The program will fail to compile
(b)One cannot be certain whether i,j,k will be printed during execution.
(c)One can be certain when i,j,k will be printed during execution.
(d)One can be certain that i and k will never be printed.
(e)One can be certain that k will never be printed.
This is what I thought the program is doing. It is creating two threads which then try to seek the monitor for the objects lock1 and lock2. Now we cannot be certain how or when the synchronized methods are going to be executed. But the variables j1 and j2 are not part of synchronized blocks. So both of them will increment by one everytime. Can't we be sure of that.
Please help me out.
Thank you very much.
Pallavi
 
Sarma Lolla
Ranch Hand
Posts: 203
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think this is correct
public static void main extends thread {
 
Pallavi Chakraborty
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Sarma,
I am sorry ..... It is
public class MyClass extends thread.
Thank you
Pallavi
 
Lakshmi Dasari
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Pallavi,
I think the correct answer is (e)

One can be certain that k will never be printed as 'k1' and 'k2' are incremented in the same synchronized block. Therefore they will always be equal. 'i' could be printed as i1 and i2 are incremented in two different synchronized blocks. So its possible that one thread is executing doit() method and another check() resulting in the output of character 'i'. j1 & j2 do not belong to any synchronized block so their values need not necessarily be equal always.
Hope this helps.
Regards,
Lakshmi.
 
Pallavi Chakraborty
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Lakshmi,
The answer is b.
Actually even I though that the answer is e.Whenever the thread seeks the monitor of the synchronized lock lock2, both k1 and k2 get incremented,which means their values are always equal.
Can you tell me what you think about j1 and j2. These two variables are part of the method doit() so whenever this method is executed their values increment.
 
Sarma Lolla
Ranch Hand
Posts: 203
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just commented both the print statements for i and j and ran teh program and did get the print for k. So it is unpredictable. But getting the print of k is happens not as frequesntly as i and j.
 
Lakshmi Dasari
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Pallavi and Sarma,
I agree (b) seems to be the best bet though (e) seemed appropriate initially. I ran the program as Sarma suggested and I did get the output of 'k' but not as frequently as 'i' and 'j'. What seems to me to be the reason is that doit() and check() method calls are independent of each other. Therefore threads could be in any of the two methods at any point of time and access the variables.Note that the method calls are not enclosed in synchronized block. If they were , then 'i','j','k' will not be printed. Pallavi, as for 'j1' and 'j2', they will be incremented by one after the method call but not equally incremented. So 'j' could be printed. I have slightly modified your code to see which thread is currently modifying the variables and which is reading them.

Here is the interesting part of the o/p.
.
.
.
Checking i,j,k -Thread2
[Thread2]
Checking i,j,k -Thread2
[Thread2]
Checking i,j,k -Thread2
Checking i,j,k -Thread1
[Thread1]
Checking i,j,k -Thread1
[Thread1]
Checking i,j,k -Thread1
.
.
.
[Thread2]
Checking i,j,k -Thread2
[Thread2Checking i,j,k -Thread1
[Thread1]
Regards,
Lakshmi.
 
Pallavi Chakraborty
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Lakshmi,
Thanks. That made things a lot clearer.
I tried to run your code by printing out the values of all the static variables when the run method is not synchronized on lock1 object.
Their are all possible combinations in each output.Sometimes i1 gets incremented while i2 does not and so on. But you and Sarma were right, i did not see kkkkkkkkk.
So, there is really no certainity of which variables are going to get incremented and which are not.
However, with the synchronized block in run() the incrementing is same.
I now get the difference
Thanks a lot
Pallavi
 
Sarma Lolla
Ranch Hand
Posts: 203
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The morale of the story is - If there are multiple threads accessing multiple variables with a break (it is not java break...) in synchronization code we shouldn't expect any thing regaridng the values of the variables.
Any thread can go to bed any time and can wake up any time.
 
Pallavi Chakraborty
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Very well put, Sarma.
Pallavi
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic