Threads not running in starting order (?)

T

Timo Nentwig

Hi!

Below I do start Thread t1 before t2. t1 tries to call print1() on a
Printer object and t1 print2() but only the first will success since it
obtains a lock on the Printer object. I'm surprised that although t1 is
started first the code prints "2". If I put a sleep(5) between the
starting of the threads t1 wins the race.

Can somebody explain?

public class SyncThreadTest
{
public static void main( String[] args )
{
new SyncThreadTest().go();
}

private void go()
{
Thread t1 = new Thread( new Runner( 1 ) );
Thread t2 = new Thread( new Runner( 2 ) );
System.out.println(t1.toString());
t1.start();

System.out.println(t2.toString());
t2.start();
}

class Runner implements Runnable
{
int i = 0;

public Runner( int i )
{
this.i = i;
}

public void run()
{
// Printer p = Printer.getInstance();
Printer p = new Printer();
// synchronized( p )
// synchronized( Printer.class )
synchronized( p.MUTEX )
{
while( true )
{
System.out.println(toString());
if( i == 1 ) p.print1();
else p.print2();

try
{
Thread.sleep( 500 );
}
catch( InterruptedException e )
{
}
}
}
}
}
}

class Printer
{
private static final Printer instance = new Printer();

public static final Object MUTEX = new Object();

public static Printer getInstance()
{
return instance;
}

public synchronized void print1()
{
System.out.println( 1 );
}

public synchronized void print2()
{
System.out.println( 2 );
}
}
 
V

Viator

There is no such guarantee in JAVA that threads will run in the order
they are started.
In fact on thread is totally independent of the other.

Amit :)
 
T

Timo Nentwig

Hmm. Well, but I can reproduce the scenario, it's *always* t2 that
obtains the lock.
 
I

Ingo R. Homann

Hi,

Timo said:
Hmm. Well, but I can reproduce the scenario, it's *always* t2 that
obtains the lock.

In fact it isn't even guaranteed that the "undefined" behaviour is *not*
reproducable! (Beware of the two "not"s in this sentence! :)

"undefined" just means that it may look different on different OSs or JVMs.

(This is similar to random numbers: They *are* reproducable! There is
just no statistical pattern in them. Or ... no such pattern someone has
recognized by now... ;-)

Ciao,
Ingo
 
M

Monique Y. Mudama

Hmm. Well, but I can reproduce the scenario, it's *always* t2 that
obtains the lock.

"Always" is a dangerous word, because it's impossible to prove.

That being said, it may be the case that the particular implementation
of the JVM you're using does always choose t2 for whatever reason, but
that another implementation (especially one running on top of a
different OS) would choose a different thread.
 
T

Thomas Hawtin

Monique said:
"Always" is a dangerous word, because it's impossible to prove.
Indeed.

That being said, it may be the case that the particular implementation
of the JVM you're using does always choose t2 for whatever reason, but
that another implementation (especially one running on top of a
different OS) would choose a different thread.

On my weirdo JVM/OS combination it's about 50/50 which comes first.
However, if I put the test in a loop (appending sleep/stop/join), it is
almost always the first thread that wins the race. That might give the
original poster an idea as to a possible cause. It might also indicate
that you should not rely on this sort of behaviour, even if it "works
for me".

Tom Hawtin
 
Z

zero

"Always" is a dangerous word, because it's impossible to prove.

That being said, it may be the case that the particular implementation
of the JVM you're using does always choose t2 for whatever reason, but
that another implementation (especially one running on top of a
different OS) would choose a different thread.

In other words, never ever make code that depends on threads running in a
particular order. If you need (part of) a thread to run before (part of) a
different one, use concurrency control.
 
J

jonb

I am trying to interrupt a thread. I have a long running thread and I
get a thead dump and find the name. Then I need this thread to be
interrupted. How do I pass the name of the thread into the java applet?


Here's my efforts so far:

public static final void InterruptThread( IData pipeline ) throws
ServiceException
{
boolean threadDone = false;
Thread toBeInterrupted = null;
String threadName = null;

IDataCursor idcPipeline = pipeline.getCursor();

idcPipeline.first("ThreadName");
threadName = (String)idcPipeline.getValue();
try {

// Pass name to Thread layer.
// toBeInterrupted = Thread[threadName];
toBeInterrupted.setName(threadName);
toBeInterrupted.join();
toBeInterrupted.currentThread().interrupt();
threadDone = true;
String errorCd = "Success";
idcPipeline.insertAfter("Success", errorCd);
}
catch(Exception e)
{
idcPipeline.insertAfter("Success", e);
//throw new ServiceException(e.getMessage());
}
finally
{
idcPipeline.destroy();
toBeInterrupted = null;
}
return;
}

I know that the Thread.setName just sets the name of the new thread to
the name that was input. This is probably not the thread I got a dump
on. How to I set the name of the thread in my service to the input name
that is type String?
 
J

jonb

I am trying to interrupt a thread. I have a long running thread and I
get a thead dump and find the name. Then I need this thread to be
interrupted. How do I pass the name of the thread into the java applet?


Here's my efforts so far:

public static final void InterruptThread( IData pipeline ) throws
ServiceException
{
boolean threadDone = false;
Thread toBeInterrupted = null;
String threadName = null;

IDataCursor idcPipeline = pipeline.getCursor();

idcPipeline.first("ThreadName");
threadName = (String)idcPipeline.getValue();
try {

// Pass name to Thread layer.
// toBeInterrupted = Thread[threadName];
toBeInterrupted.setName(threadName);
toBeInterrupted.join();
toBeInterrupted.currentThread().interrupt();
threadDone = true;
String errorCd = "Success";
idcPipeline.insertAfter("Success", errorCd);
}
catch(Exception e)
{
idcPipeline.insertAfter("Success", e);
//throw new ServiceException(e.getMessage());
}
finally
{
idcPipeline.destroy();
toBeInterrupted = null;
}
return;
}

I know that the Thread.setName just sets the name of the new thread to
the name that was input. This is probably not the thread I got a dump
on. How to I set the name of the thread in my service to the input name
that is type String?
 
M

Mike Schilling

Timo Nentwig said:
Something else:

class Foo extends Thread
{
private Text text;
public Foo()
{
// this appears to be executed by caller thread
text = new Text(shell, ...); // -> Exception
}

public void run()
{
// this appears to executed by this thread
text = new Text(shell, ...); // -> alright
}
}

new Foo().start();

Yes, you create the Foo in the current thread, then create a new thread and
execute run() in that one. No other behavior is possible.
 
M

Mike Schilling

Monique Y. Mudama said:
"Always" is a dangerous word, because it's impossible to prove.

Very true. It's quite possible that the same program running at a different
priority or with different CPU load will give different behavior. You might
be able to prove that "always" is true by looking at the implementation, but
no amount of black-box testing can prove it.
 
Z

zero

I am trying to interrupt a thread. I have a long running thread and I
get a thead dump and find the name. Then I need this thread to be
interrupted. How do I pass the name of the thread into the java
applet?

I've never tried this, so I may be completely off the mark. But, if you
have saved the thread's name, why not just save an instance to the thread,
and interrupt that?

return;
}

Why do you have that return statement?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top