Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making threads work in proper way

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.

like image 669
Mick Avatar asked Dec 07 '10 17:12

Mick


4 Answers

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.

like image 171
Nathan Hughes Avatar answered Nov 20 '22 09:11

Nathan Hughes


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
like image 38
Peter Lawrey Avatar answered Nov 20 '22 08:11

Peter Lawrey


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.

like image 1
Vincent Ramdhanie Avatar answered Nov 20 '22 10:11

Vincent Ramdhanie


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

like image 1
Eternal Noob Avatar answered Nov 20 '22 10:11

Eternal Noob