Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

Threads not running in starting order (?)

Thread view: 
Timo Nentwig - 13 Dec 2005 15:38 GMT
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 );
    }
}
Viator - 13 Dec 2005 15:41 GMT
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 :-)
Timo Nentwig - 13 Dec 2005 15:43 GMT
Hmm. Well, but I can reproduce the scenario, it's *always* t2 that
obtains the lock.
Ingo R. Homann - 13 Dec 2005 16:04 GMT
Hi,

> 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
Monique Y. Mudama - 13 Dec 2005 16:57 GMT
> 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.

Signature

monique

Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html

Thomas Hawtin - 13 Dec 2005 17:27 GMT
>>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.

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
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Timo Nentwig - 13 Dec 2005 17:30 GMT
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();

At least this is what I'm currently experience with SWT... see
http://dev.eclipse.org/viewcvs/index.cgi/platform-swt-home/faq.html?rev=1.56#uithread
Mike Schilling - 14 Dec 2005 05:47 GMT
> Something else:
>
[quoted text clipped - 15 lines]
>
> 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.
zero - 13 Dec 2005 17:32 GMT
>> Hmm. Well, but I can reproduce the scenario, it's *always* t2 that
>> obtains the lock.
[quoted text clipped - 5 lines]
> 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.

Signature

Beware the False Authority Syndrome

jonb - 13 Dec 2005 18:14 GMT
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?

> >> Hmm. Well, but I can reproduce the scenario, it's *always* t2 that
> >> obtains the lock.
[quoted text clipped - 9 lines]
> particular order.  If you need (part of) a thread to run before (part of) a
> different one, use concurrency control.
zero - 14 Dec 2005 12:37 GMT
> 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?

<snip>

> return;
> }

Why do you have that return statement?

Signature

Beware the False Authority Syndrome

jonb - 13 Dec 2005 18:16 GMT
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?

> >> Hmm. Well, but I can reproduce the scenario, it's *always* t2 that
> >> obtains the lock.
[quoted text clipped - 9 lines]
> particular order.  If you need (part of) a thread to run before (part of) a
> different one, use concurrency control.
Mike Schilling - 14 Dec 2005 05:49 GMT
>> 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.

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.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.