Threads not running in starting order (?)

Discussion in 'Java' started by Timo Nentwig, Dec 13, 2005.

  1. Timo Nentwig

    Timo Nentwig Guest

    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 );
    }
    }
    Timo Nentwig, Dec 13, 2005
    #1
    1. Advertising

  2. Timo Nentwig

    Viator Guest

    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 :)
    Viator, Dec 13, 2005
    #2
    1. Advertising

  3. Timo Nentwig

    Timo Nentwig Guest

    Hmm. Well, but I can reproduce the scenario, it's *always* t2 that
    obtains the lock.
    Timo Nentwig, Dec 13, 2005
    #3
  4. Hi,

    Timo Nentwig wrote:
    > 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
    Ingo R. Homann, Dec 13, 2005
    #4
  5. On 2005-12-13, Timo Nentwig penned:
    > 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.

    --
    monique

    Ask smart questions, get good answers:
    http://www.catb.org/~esr/faqs/smart-questions.html
    Monique Y. Mudama, Dec 13, 2005
    #5
  6. Timo Nentwig

    Timo Nentwig Guest

    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
    Timo Nentwig, Dec 13, 2005
    #6
  7. Monique Y. Mudama wrote:
    > On 2005-12-13, Timo Nentwig penned:
    >
    >>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
    --
    Unemployed English Java programmer
    http://jroller.com/page/tackline/
    Thomas Hawtin, Dec 13, 2005
    #7
  8. Timo Nentwig

    zero Guest

    "Monique Y. Mudama" <> wrote in
    news::

    > On 2005-12-13, Timo Nentwig penned:
    >> 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.
    >


    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.

    --
    Beware the False Authority Syndrome
    zero, Dec 13, 2005
    #8
  9. Timo Nentwig

    jonb Guest

    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?


    zero wrote:
    > "Monique Y. Mudama" <> wrote in
    > news::
    >
    > > On 2005-12-13, Timo Nentwig penned:
    > >> 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.
    > >

    >
    > 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.
    >
    > --
    > Beware the False Authority Syndrome
    jonb, Dec 13, 2005
    #9
  10. Timo Nentwig

    jonb Guest

    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?


    zero wrote:
    > "Monique Y. Mudama" <> wrote in
    > news::
    >
    > > On 2005-12-13, Timo Nentwig penned:
    > >> 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.
    > >

    >
    > 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.
    >
    > --
    > Beware the False Authority Syndrome
    jonb, Dec 13, 2005
    #10
  11. "Timo Nentwig" <> wrote in message
    news:...
    > 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.
    Mike Schilling, Dec 14, 2005
    #11
  12. "Monique Y. Mudama" <> wrote in message
    news:...
    > On 2005-12-13, Timo Nentwig penned:
    >> 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.
    Mike Schilling, Dec 14, 2005
    #12
  13. Timo Nentwig

    zero Guest

    "jonb" <> wrote in
    news::

    > 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?


    --
    Beware the False Authority Syndrome
    zero, Dec 14, 2005
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fernando

    starting threads from servlets

    Fernando, Apr 29, 2005, in forum: Java
    Replies:
    4
    Views:
    17,312
    Lee Ryman
    Apr 29, 2005
  2. Will McGugan

    overhead of starting threads

    Will McGugan, May 23, 2005, in forum: Python
    Replies:
    2
    Views:
    358
    Will McGugan
    May 23, 2005
  3. Pedro Pinto

    Java Threads - Get running threads

    Pedro Pinto, Apr 8, 2008, in forum: Java
    Replies:
    2
    Views:
    1,424
    Arne Vajhøj
    Apr 9, 2008
  4. Junkone

    some threads are not starting

    Junkone, Jan 3, 2008, in forum: Ruby
    Replies:
    2
    Views:
    96
    Junkone
    Jan 3, 2008
  5. Max Williams
    Replies:
    3
    Views:
    169
    Robert Klemme
    Jan 6, 2009
Loading...

Share This Page