Win a copy of Five Lines of Code this week in the OO, Patterns, UML and Refactoring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Liutauras Vilda
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • fred rosenberger
  • salvin francis
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Carey Brown

J@Whiz question

 
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Question from J@Whiz :
What will be the output on compiling/running the following code?
public class MyThread implements Runnable
{
String myString = "Me ";
String yourString = "You";
public void run()
{
for (int i=0; i < 2; i++)
{
myString.concat(" to Me ");
System.out.print(myString);
yourString.concat(" for You ");
System.out.println(yourString);
}

}
public static void main(String[] args)
{
MyThread t = new MyThread();
new Thread(t).start();
new Thread(t).start();
}
}

a.Prints
Me to You You to Me
Me to You You to Me
Me to You You to Me
Me to You You to Me
b.Prints
Me to You Me to You
Me to You Me to You
Me to You Me to You
Me to You Me to You
c.Prints
Me to You You to Me
You to Me Me to You
Me to You You to Me
You to Me Me to You
d.Output cannot be determined
e.Prints
Me You
Me You
Me You
Me You
Their answer:
E is correct. Here two threads are constructed one after another. When start() method of first thread is called, the run() method will be called. Inside the run method, the loop will be executed twice. Please note that concat() method on String object doesn't change the value of original object, it creates new String object. Thus the values of myString and youString will remain unchanged. Thus run will be called twice and will print twice Me You each time it(run) is invoked.
My point: The above explanation is right about string concatenation but is not mentioning the fact that we don't have synchronized run() or code block . So I think we could have an output like this :
Me
Me You
You
..... (first thread start prints Me, cease execution to second thread which prints Me You ....)
So I think d is the answer.
What do you think ?
[ January 22, 2002: Message edited by: Salamina Daniel ]
 
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Salamina
Well I'd put d. for the same reason, fwiw.
This is not the only time that I have found myself puzzling over a question when I think that one option is not exactly right and there is an answer of None of the above or similar.
All the best
Simon
 
Ranch Hand
Posts: 178
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Guys just remember String objects are immutable, they can never ever change, period!
Also in the for loop, the first statement,
myString.concat(" to Me ");
creates a new string "Me to Me", but myString never changes because of string immutability! The new string "Me to Me" is lost since we don't save it to anything!
Try altering the body of the run method to this:
public void run()
{
String s1;
String s2;
for (int i=0; i < 2; i++)
{
s1=myString.concat(" to Me ");
System.out.print(s1);
s2=yourString.concat(" for You ");
System.out.println(s2);
}
}
[ January 22, 2002: Message edited by: Rajinder Yadav ]
 
Ranch Hand
Posts: 5390
1
Spring Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ans should be 'd'
some one throw some light on Why 'e' ?
CMIW
 
Simon Whitehouse
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Rajinder
Our query is not with string immutability but with the fact that one thread may interrupt the other one in between the two System.out.println statements. Because of that we think that it is not possible to determine what the screen output will be.
So our query hinges on threads and not Strings.
All the best
Simon
 
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Salamina,
you are correct, the correct answer should be D. I think what happened is someone at J@Whiz ran that test program once, looked at the output, and just assumed the output would always be the same. That's why I'm really starting to question the quality of some of these sample tests.
Try this program, it's a simple variation of the original :

Repeated again without CODE tags to help copy&paste:
public class MyThread implements Runnable
{
String myString = "Me ";
String yourString = "You";
public void run()
{
for (int i=0; i < 2; i++)
{
myString.concat(" to Me ");
System.out.print(myString);
yourString.concat(" for You ");
System.out.println(yourString);
}
}
public static void main(String[] args)
{
MyThread t = new MyThread();
for (int i = 0; i < 100; i++)
{
Thread a = new Thread(t);
Thread b = new Thread(t);
a.start();
b.start();
try
{
a.join();
b.join(); //wait until both threads finish to continue loop
}
catch (Exception ex)
{
}
System.out.println("");
}
}
}
The difference is, I continuously created two threads, start them, and wait for both of them to finish before I start two more threads. (This is a good example of using join() )
The output from one of my runs is:
Me Me You
You
Me Me You
You
and another is
Me You
Me Me You
You
Me You
So you can see the effects of non-deterministic thread scheduling behaviour.

Rob
 
Ranch Hand
Posts: 281
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[off topic]
he he..just had to comment on the duplicate posting of the code to aid in cut and paste
If they just enabled HTML tags to be used again in this forum, we could get around this problem since users could be told to just format their code within in <PRE></PRE> tags and everything would be grovey. It's amazing how many things this would help with:
1) Everyone could cut and paste without losing any formatting.
2) The display would look right on the forum with indents, tabs, etc.
3) The font size would be the default...not some drastically reduced size.
 
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob,


The difference is, I continuously created two threads, start them, and wait for both of them to finish before I start two more threads. (This is a good example of using join() )


Rob or Somebody, I was wondering if you could elaborate a little more on what this "revised" code is doing, ie how are they continuously being created and what the effects are of join()
TIA
 
Rob Ross
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Rob Ross:


Look at the main method. The Threads are now being instantiated in a loop. I create two threads, then start them. Then I wait for both to quit via join(). When I call join, it causes the current thread to wait until the other thread has finished. When it finishes, my thread resumes.
When both threads I had previously started are done running, then I create two more, and wait for them to stop. I repeat this whole process 10 times. I'm running it in a loop so you can see that occasionally, the threads print out messages in different orders, showing that you cannot predetermine the order of output.
I hope this explains it!
Rob
 
Paul Salerno
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Thanks for your quick reply.


When I call join, it causes the current thread to wait until the other thread has finished. When it finishes, my thread resumes.


When you call a.join() the current thread running would be the last statement b.start() which must wait until the a.start() thread has finished running.
Also you mentioned that you invoke this 10 times, but I noticed 100 in the for loop
Finally, why isn't "to me" or "for you" ever being printed?
 
Rob Ross
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yea, the 10 is a typo.
For the other question, scan up a bit to a post by Rajinder Yadav ...he explains what's going on with the concat().
Rob
 
Paul Salerno
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob,
When you call a.join() the current thread running would be the last statement b.start() which must wait until the a.start() thread has finished running.
Am I correct on this?
 
Rob Ross
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes.
calling a.join() causes the current thread to wait until thread a is done executing, i.e, it's run method exits. The next line is
b.join()
and this will wait until thread b is done before continuing.
It's very likely that b will already be dead (done running) by the time the call to a.join() returns, but it does no harm in that case. If b is still running, then the current thread just waits until it's done before continuing with the next loop iteration.
Rob
 
Paul Salerno
Ranch Hand
Posts: 172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


When you call a.join() the current thread running would be the last statement b.start() which must wait until the a.start() thread has finished running.
Am I correct on this?
Yes.
calling a.join() causes the current thread to wait until thread a is done executing, i.e, it's run method exits. The next line is b.join()
and this will wait until thread b is done before continuing.


Rob I'm sorry I'm still a little fuzzy on this, what the "current thread is".
We have:
a.start()
b.start()
a.join() -- when it reaches here the current thread is B; once thread B's run method exits, Thread A is executed
b.join() -- when it reaches here the current thread is A; once thread A's run method exits, Thread B is executed
Look forward to closing this issue too.
thanks again Rob!
-Paul
 
Rob Ross
Bartender
Posts: 2205
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Paul Salerno:

Rob I'm sorry I'm still a little fuzzy on this, what the "current thread is".
We have:
a.start()
b.start()
a.join() -- when it reaches here the current thread is B; once thread B's run method exits, Thread A is executed
b.join() -- when it reaches here the current thread is A; once thread A's run method exits, Thread B is executed
Look forward to closing this issue too.
thanks again Rob!
-Paul



I don't know how much you know about threads Paul, but you might want to look at the sun java site and take some tutorials if this is really confusing to you. It's hard to explain threads...it just takes a while to "get it". A thread is a "thread of control", and each thread executes statements.
When the JVM invokes the main method and starts your application, the main method is running in the main user thread. This thread executes all the statements in the main method, including a.join() and b.join(), so your comments about 'a' being the current thread and 'b' being the current thread don't make sense. When the main user thread executes the a.join() command, it stops its execution until thread a, which is a different thread also running code, is done. Then the main user thread executes the b.join() statement, and it waits at that point until the b thread, also off running code, is done. Then the main user thread continues, on to its next loop iteration.
There are three threads running more-or-less parallel all the time in this application - the main user thread, and two threads it spawns, referenced in the main user thread in variables a and b. The concept of "current thread" means, whichever thread happens to be invoking a particular method at the time the "what is the current thread" question is asked. In this example, because of the specific code in the main method, the main user thread is always the current thread when the statements a.join() and b.join() are called.
Rob
 
    Bookmark Topic Watch Topic
  • New Topic