Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

About threads...!!

Posted on 2002-03-31
17
Medium Priority
?
193 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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

Build and deliver software with DevOps

A digital transformation requires faster time to market, shorter software development lifecycles, and the ability to adapt rapidly to changing customer demands. DevOps provides the solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses

704 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