2010-12-07 79 views
5

我剛開始學習線程,並誤解了它們的工作原理。使線程正常工作

這裏是我的類:

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. 
*/ 

爲什麼我總是得到所有在第一,之後「......完成」的消息「......開始」的消息?無論我開始有多少個線程,我總會看到:

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 

線程的目的不是並行執行嗎?
也許我需要同步一些東西?還是犯了粗心的錯誤?要麼…?
請解釋。

UPDATE:

爲什麼我看不到,讓我們說:

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

謝謝大家接受治療。

+0

你的英文很好。好問題。 – sje397 2010-12-07 17:38:14

+0

@ sje397謝謝你,先生! – Mick 2010-12-07 17:55:03

回答

2

線程是並行的。否則,在下一個「開始」之前,您會看到每個線程「已完成」。

減慢線程速度的一種簡單方法是使用Thread.sleep(10 * 1000);睡覺10秒(10,000毫秒)

編輯:一個簡單的方法看到線程交錯是有一個固定大小的線程池。

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; 
     } 
    }); 
} 

打印

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 
2

看起來不錯。您可以從輸出中看到線程是交錯的。線程開始啓動,獲得上下文切換,並被調度程序選中,例如,您可以看到線程8跳到線程5之前的位置。如果所有的數字都是一致的,這將是奇怪的,但這似乎很好。

使用睡眠時間,就像Peter Lawrey所說的那樣,因此您可以更改每個線程更容易處理的時間。正如你的例子所展示的,開始一個過程需要很多時間,看起來合理,你的所有線程都應該在完成之前開始。

1

如果您在run()方法中放置了一個從1到20的簡單循環,則可以更好地看到執行的交錯。

1

如果你想看到一個「隨機」的開始和結束你可能要添加一個

或類似到線程。