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 sta开发者_如何学Gorted
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.
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.
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
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.
There is a difference between multi-threading and parallel processing... check this out...
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.
精彩评论