5

I just have started learning threads and come upon misunderstanding of how they work.

Here is my class:

public class MyThread extends Thread {
    private static int NUM = 0;
    private int id;

    public MyThread() {
        id = NUM++;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new MyThread().start(); 
        }
    }

    public void run() {
        System.out.println(id + " started");

        try {
            Process p = Runtime.getRuntime().exec("javac -version");
            p.waitFor();
        } catch (Exception e) {
            System.out.println("Call a doc!");
        }

        System.out.println(id + " finished");
    }
}

/*
Just a sidenote.
I am creating new javac process just to slow an application down.
Simple System.out.println(…) is a way faster.
*/

Why do I always get all "… started" messages at first and after that "… finished" messages? No matter how many threads have I started, I always see:

0 started
1 started
2 started
3 started
4 started
5 started
6 started
7 started
8 started
9 started
0 finished
1 finished
3 finished
4 finished
8 finished
5 finished
2 finished
6 finished
9 finished
7 finished

Isn't the purpose of threads to parallelize execution?
Maybe I need to synchronize something? Or made careless mistake? Or…?
Explain, please.

UPDATE:

Why don't I see, let's say:

0 started
1 started
0 finished
2 started
1 finished
2 finished

Thank you all for treatment.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
Mick
  • 51
  • 4

5 Answers5

2

The threads are parallel. Otherwise you would see each thread "finished" before the next one "started"

A simple way to slow down a thread is to use Thread.sleep(10*1000); to sleep for 10 seconds (10,000 milli-seconds)

EDIT: a simple way to see threads interleaving is to have a fixed size thread pool.

ExecutorService pool = Executors.newFixedThreadPool(4);
for (int i = 0; i < 10; i++) {
    final int id = i;
    pool.submit(new Callable<Void>() {
        public Void call() throws InterruptedException {
            System.out.println(id + " started");
            Thread.sleep(1000);
            System.out.println(id + " finished");
            return null;
        }
    });
}

Prints

0 started
1 started
2 started
3 started
0 finished
4 started
1 finished
5 started
2 finished
6 started
3 finished
7 started
4 finished
8 started
5 finished
6 finished
9 started
7 finished
8 finished
9 finished
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Yeah, they're parallel - but I am guessing he's asking why, if he creates hundreds of threads, none finish during the main loop. – sje397 Dec 07 '10 at 17:37
  • You start the threads as fast as you can, there is no delay. Each thread takes much longer to execute so they all start before the first one finishes. – Peter Lawrey Dec 08 '10 at 20:18
2

Looks ok. You can see from your output that the threads are interleaving. threads are getting started, get context-switched, and get picked by the scheduler, you can see where thread 8 jumps ahead of thread 5, for instance. If all the numbers were in order consistently it would be strange but this seems fine.

Use sleep time, like Peter Lawrey suggests, so you can alter how long each thread takes more easily. As your example stands, starting a process takes so much time it seems reasonable all your threads should get started before any finish.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
1

If you put a simple loop to count from 1 to 20 in the run() method you may see the interleaving of the execution better.

Vincent Ramdhanie
  • 102,349
  • 23
  • 137
  • 192
1

There is a difference between multi-threading and parallel processing... check this out...

Community
  • 1
  • 1
Eternal Noob
  • 2,717
  • 5
  • 27
  • 41
1

If you want to see a "random" starting and ending you might want to add a

Thread.sleep(new Random().nextInt(1000)); 

or similar to the threads.

morja
  • 8,297
  • 2
  • 39
  • 59