• Post Reply Bookmark Topic Watch Topic
  • New Topic

A question for All  RSS feed

 
Rahul Mahindrakar
Ranch Hand
Posts: 1869
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi
I do not know why Line 1 is not printing out "in run". Is it something I am missing.


Regds.
Rahul P. Mahindrakar
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tricky, tricky Rahul.
I've never seen this tried and can't figure why you'd want to do it, but you're creating the second thread (u) with another thread as its run delegate, using the <code>Thread</code> ctor that takes a <code>Runnable</code> argument. When you create a thread this way, it executes the <code>run()</code> method of the <code>Runnable</code> argument. In your case, the <code>run()</code> method that actually gets invoked by thread u is <code>t.run()</code>, which exits rather quickly. By the time thread u tries to call it, thread t is in the dead state. Of course, a dead thread can't be restarted.
If you insert something like <code>while (true) {}</code> after the <code>println()</code> call in demo1, thread t won't be dead when thread u invokes its <code>run()</code> method, and you'll see both lines of output.
Usually, you create your own object implementing <code>Runnable</code> and hand that directly to the <code>Thread</code> ctor; your sample will also work if you create thread u with <code>Thread u = new Thread( new demo1() );</code>
P.S. It'll also work if you reverse the order in which you start the threads, so t isn't dead when u tries to start.
P.P.S. I could have sworn I ran your original sample before I posted, but maybe not. In any event, I just ran it about 50 times and it printed both lines of output in every case. I still think the reasoning I gave regarding dead threads as run delegates is OK, though, because when I put a time-wasting loop <code>for (int i = 0; i < 100000; i++);</code> between the two <code>start</code> calls, it only printed the first output line. I have a dual-processor machine, by the way.
[This message has been edited by jply (edited August 25, 2000).]
[This message has been edited by jply (edited August 25, 2000).]
 
deekasha gunwant
Ranch Hand
Posts: 396
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi ,
The program printed 'in run ' on my pc twice.
how can it be explained.
regards
deekasha
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think the only way it'll print both lines of output is if the first thread is still alive at the time the second is started. Try putting some kind of time-waster (see above) in between the start calls. On my machine, that caused the program to print only one line of output (the one from the first thread).
Please let me know if that works. If it doesn't, I'm at a loss to explain the behavior Rahul observed.
 
Ramya Sivakumar
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys,
this is my first reply.correct me if i am wrong.
jply.. u r correct.when the 'u' thread is started,'t' is completed and becomes dead.Thats why only one 'in run' is printed.
if u put sleep() in the run method of demo1 class,'u' will be started before 't' expires.Thus printing two 'in run'.
Thanks,
RamyaSivakumar.
 
prasanth chiru
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,
The program is printing some times only in run and sometimes in run in run(twice).
Prasanth
 
prasanth chiru
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi jply,
I don't think the logic given by you is correct. I inserted these lines in the code after u.start()(ie, line 1 marked in program).
if(!t.isAlive())
System.out.println("Alive");
That means if thread t is alive, it should not print "Alive" and
has to print "in run" second time (u.run(), as you said). Is it correct. But it is not happening. It is not printing "Alive" and also it is not printing "in run" second time.
Pl. correct if I am wrong.
 
Jerry Pulley
Ranch Hand
Posts: 221
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prasanth;
That's because thread scheduling is, for practical purposes, non-deterministic. There's no way to guarantee which of two runnable threads will actually be running at a given instant.
jply
 
Jerry Pulley
Ranch Hand
Posts: 221
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Prasanth;
Both our last posts are timed at 12:08; my previous post referred to your 11:45. About your 12:08: Using <code>isAlive()</code> is a good idea (one of us should have tried that before, Rahul), but I have a couple of questions about your implementation of it.
First, why are you saying <code>!isAlive()</code>? Seems like you'd want to print "Alive" if the test returned <code>true</code>, but your code prints "Alive" if <code>isAlive()</code> returns <code>false</code>. It's confusing.
Second, and more importantly, what if a time slice occurs after the test but before the call to start? The thread could be alive at the time you check its liveness but dead before the other one gets going. I swiped your idea and wrote this little thing; it addresses that problem by placing the liveness check in <code>run()</code>.<pre><code>
class Demo2 {
public static void main(String[] args) {
try {
demo1 xx = new demo1();
Thread t = new Thread( xx, "ThreadT" );
Thread u = new Thread( t, "ThreadU" );
xx.setThreadT( t );
t.start();
if (args.length > 0 && args[0].equals( "delay" )) {
for (int i = 0; i < 100000; i++);
}
u.start();
} catch (Exception e) {
System.out.println(e);
}
}
}
class demo1 implements Runnable {
private Thread threadT = null;
public void setThreadT( Thread t ) {
threadT = t;
}
public void run() {
if (threadT != null && Thread.currentThread() != threadT) {
if (threadT.isAlive()) {
System.out.println( threadT.getName() + " is alive" );
} else {
System.out.println( threadT.getName() + " is not alive" );
}
}
System.out.println( Thread.currentThread().getName() + " in run");
}
}</code></pre>
It's kind of a kludge, I know. Given the check that says "do the test only if I'm not threadT", only thread <code>u</code> will make the liveness check. If on any given execution you see a "ThreadU in run" output line, you'll also see a "ThreadT is alive" line. This shows that <code>t</code> is alive whenever <code>u</code> runs. This isn't a complete proof because we never get the negative check (I did one like that, but it got too messy), but it at least supports my point. (At least, this is the behavior I get.)
If your computer, like mine, needs some help to actually let one thread die before the other runs, say "java Demo2 delay" on the command line and the time-waster will run in between the <code>start()</code> calls.
jply

[This message has been edited by Jerry Pulley (edited October 03, 2000).]
 
Raghvendra Sharma
Ranch Hand
Posts: 82
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear rahul,
This code is working very well as such without any changes.
I'm running jdk1.3 win98.

raghav..
 
Vivek Nambiar
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I changed the code slightly and it works printing both the start() methods

the answer = TT
in run
in run

The conclusion that I draw out here is that the threads need some time to initialize.

 
anurudh
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all
code is running and giving
in run
in run
please have a final verdict on these
thanks
Anurudh
 
Bharatesh H Kakamari
Ranch Hand
Posts: 198
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Thread t=new Thread(xx);
Thread u = new Thread(t);

The first line is fine. You are creating a Thread object passing xx. In the second line, a Thread takes a object of Runnable. You are passing an object of class Thread which anyway implements Runnable. So this object casting is fine.

t.start();
u.start();

Here again, t.start() is fine. It starts the Thread represented by reference t. Now there can be two situations :
1) Either the t Thread completes its execution and returns and then the second statement u.start() is executed. As it is possible to execute a dead thread's method 'in run' is printed twice.
ii) But if 't' has become unreachable then nothing is printed.
Please provide your comments.
 
Jerry Pulley
Ranch Hand
Posts: 221
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wow, this thread just keeps going and going... Good one, Rahul.
Bharatesh,
Your comment in 1) is not quite correct. It is possible to execute a Thread's run() method after the Thread is dead, but it's not possible to start() a dead Thread.
What is bothering me about the example is why the call u.start() doesn't throw an IllegalThreadStateException. For instance, if the code were something like<pre>
...
t.start();
...//wait a few milliseconds for t to die
t.start();
...</pre>
then we'd definitely see the exception. I can only surmise that the failure to start has to do with the state of u's run delegate (t) while the exception depends on the state of the Thread itself (u). I don't know this for sure, but it seems to fit the evidence.
As for why people often see output like<pre>
in run
in run</pre>, this behavior is very timing- and scheduling-dependent, and that's going to vary from machine to machine and VM to VM. See some of the above code samples for a way to guarantee that t has a chance to complete before u is started.
Jerry
P.S. Anurudh, please check out http://www.javaranch.com/name.jsp and register an appropriate user name.
P.P.S. Vivek, I don't get it. Could you give the reasoning that leads you to the conclusion that the threads need time to initialize? Once the statement <code>Thread u = new Thread(t);</code> has completed the object u is fully initialized and ready to go. The only timing-dependent thing I can see in this example is thread scheduling, which doesn't happen until after <code>start()</code> is called.
[This message has been edited by Jerry Pulley (edited December 19, 2000).]
 
Mahanthi Bukkapatnam
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,



Think what explanation jply gave is correct to some extent. I tried the code to get an idea as to what was happening. The original code did print "in run", only once. I tried to make the first thread run for a shorter time than the second ( i used a loop to print 10 numbers for the first thread and made the
second thread loop to print 20 numbers with a time delay). I was expecting that the moment the first thread completes execution, the second thread will stop. Guess what, the second thread continued to run and completed.

Then i was wondering if the Thread class maintains the same state though you pass a runnable interface or a Thread Object and should also be maintaining if any threads are running the run() method. If none are running as of yet, once the run method completes, it enters the dead state. If in the meantime, some
other thread has started, it would wait for that to complete. Something like reference count logic would have been employed. To test this idea, i tried to clone the Thread object t. To my expectation both the "in run" printed.
The code i used is as follows :



<Pre>
class MyThread extends Thread implements Cloneable
{
MyThread( Runnable r ) {
super( r );
}
public Thread copy() {
Thread t = null;
try {
t = (Thread) super.clone();
}catch( Exception e ) {
System.out.println( "Exception " + e.getMessage() );
}
return t;
}
public void start() {
super.start();
}
}
public class demo
{
public static void main(String[] args)
{
try{
demo1 xx=new demo1();
MyThread t = new MyThread(xx);
Thread u = (Thread) t.copy(); // Cloning takes place here.

t.start();
u.start(); // Line 1

// this prints nothing; no exceptions no compile time errors. what's going on???
}
catch(Exception e){
System.out.println(e);
}
}
}
class demo1 implements Runnable
{
public void run() {
System.out.println("in run");
}
};
</pre>

Then i wanted to try and see if the internal thread state really changes after the thread completes.
<pre>
t.start();
Thread u = (Thread) t.copy(); // Cloning takes place here.
u.start(); // Line 1
</pre>
and at the point of cloning i got an IllegalThreadStateException.
Regards
 
Mahanthi Bukkapatnam
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi


In case you want to know how i managed the second thread to run longer than the first thread, heres the code

<pre>
class demo1 implements Runnable
{
static boolean counterSet = false;
int counter = 1;

public void run() {

int localCounter = counter;
boolean localFlag = counterSet;

if( !counterSet ){
counter = 20;
counterSet = true;
}
for(int i=0; i < localCounter ; i++ ) {

if( localFlag )
System.out.print( "Second Thread : " );
else
System.out.print( "First Thread : " );

System.out.println( "in run" + i);
try{
Thread.sleep( 400 );
}catch( Exception e ) { }
}
}
};
</pre>
Regards


 
Kalpesh Soni
Ranch Hand
Posts: 312
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi rahul, regarding the first question in the post
this is from Thread.java


i think that explains everything


------------------
KS
 
Kalpesh Soni
Ranch Hand
Posts: 312
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi
i have made some changes to the original code of rahul
seems interesting to me
if you run it several times you might get to see 3-4 types of different outputs

i hope it will help


------------------
KS
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!