Solved

About threads...!!

Posted on 2002-03-31
17
185 Views
Last Modified: 2010-03-31
I have a little confusion about the way threads works on a NT platform. According to the JDK documentation NT runs time slicing to schedule threads. This would mean that if I put two threads to the running state, eventually they will run, but there will not be any specific order to which will run. I mean if I have this two lines in my code:



myThread1.start();(run will call this line System.out.println("Thread1"); three times)
myThread2.start();()();(run will call this line System.out.println("Thread2"); three times)

I would spect that from the point of view of HUMANS my main thread, and the other two together will run in parallel. I know that they in the real life will run sequencially, but the effect you get on human is that
they are running at the same time. Thus, if I execute a piece of code where I have these two lines I would spect that the output to the console would be print the words Thread1 and Thread2 without any specific order, but when I execute this code I get the output of the first thread and then, following, the output for the second thread. It is like the system is running them sequencially one after the other and not in parallel using time slicing.

Could anybody explain me????

Thanks in advance.
0
Comment
Question by:dyma82
  • 9
  • 5
  • 3
17 Comments
 
LVL 92

Expert Comment

by:objects
ID: 6909546
Sounds like Thread 1 is simply completing before Thread 2 gets a chance to run. As you say there is no specific order.
Try printing the message 100,000 times and see what happens, or call Thread.yield() after your println() call.
0
 
LVL 4

Expert Comment

by:pellep
ID: 6910101
Well, the NT scheduler is not just "time-slicing". Since the the context-switch required by the subsystem to change focus from one thread to another is relatively processor-heavy, there is quite a bit of intelligence built in. It is very hard to exactly determine when NT will decide to switch execution from one thread to another. There is a bit of analyzing done by the NT subsystem to optimize usage. In your case, NT will most likely determine that the oprations beeing done by thread 1 are so "light" that it wont spend resources doing a context-swich after each sysout operation, but rather do them all at once and then switch focus to thread 2. This, of course, leads to problems when developing real-time systems that depend on commands beeing executed in a strict order.
0
 
LVL 1

Author Comment

by:dyma82
ID: 6910105
Well, that is exactly what is happening when you run the code. Thread1 runs first and only when it is done, then Thread2 runs. Thus, this is not time slicing. I don't even think this is threading. However, both thread runs in parallel with the main thread (time slicing between the main thread and the rest of the threads). As far as I know that is not suppse to be like that. Supposely, thread should run following a time-slicing pattern, and the code does NOT has to programatically schedule which thread is going to run using yield or join. This should be taken care of by the thread scheduler in coordination with the underlying operating system.

Any help with this???
0
 
LVL 1

Author Comment

by:dyma82
ID: 6910115
Pellep:

I just set each thread to output text every multiple of 100, and made them loop 1,000,000 times, so that if that were the case, at least one text output from Thread2 should be inserted between all those text outputs from Thread1. However, it never happened like that. It kept executing both threads one after the other in sequencial order.

As far as I know NT uses time-slicing to schedule new threads into running. Unix don't, however.
0
 
LVL 4

Expert Comment

by:pellep
ID: 6910117
To the best of my knowledge, at least sun's windows NT JVM relies entierly on the NT scheduler (ie, every Thread in the java world is, in fact, a proper thread in NT).
0
 
LVL 4

Expert Comment

by:pellep
ID: 6910118
To the best of my knowledge, at least sun's windows NT JVM relies entierly on the NT scheduler (ie, every Thread in the java world is, in fact, a proper thread in NT).
0
 
LVL 4

Expert Comment

by:pellep
ID: 6910129
public class ThreadTest implements Runnable {
   
    public static int RUN_TIMES = 1000000;
    public static int LOOP_WAIT_TIME = 100;
    /** Creates new ThreadTest */
    public ThreadTest() {
    }
   
    public void run() {
        for ( int i = 0 ; i < RUN_TIMES ; i++) {
            System.out.println("Thread:" + Thread.currentThread().getName());
            try { Thread.sleep(LOOP_WAIT_TIME); } catch (Throwable t) {}
        }
    }
    public static void main(String args[]) {
        Thread t1 = new Thread(new ThreadTest());
        Thread t2 = new Thread(new ThreadTest());        
        t1.start();
        t2.start();
    }
}

Gives the expected result, ie the output is first from thread 1, then thread 2 and so on. I don't know how your code works.
0
 
LVL 1

Author Comment

by:dyma82
ID: 6910134
Pellep:

I just set each thread to output text every multiple of 100, and made them loop 1,000,000 times, so that if that were the case, at least one text output from Thread2 should be inserted between all those text outputs from Thread1. However, it never happened like that. It kept executing both threads one after the other in sequencial order.

As far as I know NT uses time-slicing to schedule new threads into running. Unix don't, however.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Author Comment

by:dyma82
ID: 6910141
Pellep:
That is the result I was expecting, but without having to programatically put one of the thread to sleep. I think I could do that if it were really necessary (like within an io operation), but in this very simple case I would let the underlaying OS to do that. However, again, it executes both thread sequencially when it should do that with a random time-slicing pattern.
0
 
LVL 4

Expert Comment

by:pellep
ID: 6910159
Hmm. No sleeping, you say. That is somewhat nasty. Not a specific JAVA problem though, as I have seen that behaviour in VB for instance as well. If you create a long loop, it will almost freeze the system, as the scheduler doesn't remove focus from the thread without DoEvents.

IO libraries (if they are well written) should release focus (with sleep() or something like that) within blocking calls.
0
 
LVL 1

Author Comment

by:dyma82
ID: 6910173
Pellep:
That is the result I was expecting, but without having to programatically put one of the thread to sleep. I think I could do that if it were really necessary (like within an io operation), but in this very simple case I would let the underlaying OS to do that. However, again, it executes both thread sequencially when it should do that with a random time-slicing pattern.
0
 
LVL 1

Author Comment

by:dyma82
ID: 6910408
Pellep:
That is the result I was expecting, but without having to programatically put one of the thread to sleep. I think I could do that if it were really necessary (like within an io operation), but in this very simple case I would let the underlaying OS to do that. However, again, it executes both thread sequencially when it should do that with a random time-slicing pattern.
0
 
LVL 1

Author Comment

by:dyma82
ID: 6910449
Ok. I found what the problem was. It happened that the length of the loop I was using to keep busy each thread was too short, so the threads were able to finish their task within the time-slice where they were allowed to run. Thus, it looked like they were being executed sequencially. However, as soon as I increased the length of the loop to some astronomical value, the little program started behave like it should, following a random time-slice pattern. I used the following code to test this:

package tester2;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2002</p>
 * <p>Company: </p>
 * @author unascribed
 * @version 1.0
 */


  public class tester2 extends Thread {
    private int c;

    public tester2(int i)
    {
      this.c = i;
    }
    public void run() {
      if(c == 1)
      {
        for (int y = 0; y < 10000000; y++) {
          if((y == 500000)||(y == 9000000)) {System.out.print(y);System.out.println("   Thread : "+c+" running");}
        }
      }
      else
      {
        for (int y = 0; y < 10000000; y++) {
          if((y == 500000)||(y == 9000000)) {System.out.print(y);System.out.println("   Thread : "+c+" running");}
        }
      }

        //if (y == 95) { System.exit(0); }

    }

    public static void main(String [] args) {
      tester2 r = new tester2(1);
      tester2 r2 = new tester2(2);
      Thread t1 = new Thread(r);
      Thread t2 = new Thread(r2);
      t1.start();
      System.out.println("Starting sencond thread....!!!");
      t2.start();
      System.out.println("Done....!!!");
    }
  }
0
 
LVL 1

Author Comment

by:dyma82
ID: 6910464
Ok. I found what the problem was. It happened that the length of the loop I was using to keep busy each
thread was too short, so the threads were able to finish their task within the time-slice where they
were allowed to run. Thus, it looked like they were being executed sequencially. However, as soon as
I increased the length of the loop to some astronomical value, the little program started behave like
it should, following a random time-slice pattern. I used the following code to test this:

package tester2;

/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/


 public class tester2 extends Thread {
   private int c;

   public tester2(int i)
   {
     this.c = i;
   }
   public void run() {
     if(c == 1)
     {
       for (int y = 0; y < 10000000; y++) {
         if((y == 500000)||(y == 9000000)) {System.out.print(y);System.out.println("   Thread : "+c+"
running");}
       }
     }
     else
     {
       for (int y = 0; y < 10000000; y++) {
         if((y == 500000)||(y == 9000000)) {System.out.print(y);System.out.println("   Thread : "+c+"
running");}
       }
     }

       //if (y == 95) { System.exit(0); }

   }

   public static void main(String [] args) {
     tester2 r = new tester2(1);
     tester2 r2 = new tester2(2);
     Thread t1 = new Thread(r);
     Thread t2 = new Thread(r2);
     t1.start();
     System.out.println("Starting sencond thread....!!!");
     t2.start();
     System.out.println("Done....!!!");
   }
 }


Experts-exchange should provide functionality to let the question to be solved by the very same user who posted it. That could also happen, like in this case. Thus, the question could remain part of the community knowledge and the user would not have to delete!
0
 
LVL 92

Accepted Solution

by:
objects earned 100 total points
ID: 6911192
That's pretty much what I said in the first place, that the thread was finishing before the other one got a chance to run.
0
 
LVL 1

Author Comment

by:dyma82
ID: 6911604
I really apologize for not noticing your answer, but the site was behaving really strange, and many answers were repeated several times. I probabily got confused with all these repetitions. You certainly answered my question, and I am awarding you your deserved points.

Accept my apologies again and
Thanks a lot for your time guys.
0
 
LVL 92

Expert Comment

by:objects
ID: 6911957
No worries, thanks for the points.
Make sure you also have a look at the yield() method, it's useful for ensuring that Thread's are 'polite'.

http://www.objects.com.au
Brainbench MVP for Java 1
http://www.brainbench.com
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now