2016-02-05 57 views
1

這是我的程序。線程輸出不按預期執行

class SimpleThread extends Thread { 
    public SimpleThread(String str) { 
     super(str); 
    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      System.out.println(i + " " + getName()); 
      try { 
       sleep((int)(1000)); 
      } catch (InterruptedException e) {} 
     } 
     System.out.println("DONE! " + getName()); 
    } 
} 



    class TwoThreadsTest { 
    public static void main (String[] args) { 
     new SimpleThread("Jamaica").start(); 
     new SimpleThread("Fiji").start(); 
    } 
} 

我得到輸出

0 Jamaica 
0 Fiji 
1 Fiji 
1 Jamaica 
2 Jamaica 
2 Fiji 
3 Fiji 
3 Jamaica 
4 Fiji 
4 Jamaica 
5 Fiji 
5 Jamaica 
6 Fiji 
6 Jamaica 
7 Fiji 
7 Jamaica 
8 Jamaica 
8 Fiji 
9 Fiji 
9 Jamaica 
DONE! Fiji 
DONE! Jamaica 

我懷疑.. 1)線程牙買加被稱爲第一 要求它睡1000毫秒。 然後線程斐濟被稱爲 它應該打印並要求進入睡眠1000毫秒。 但我得到如上所示的輸出。 爲什麼它不交替和印刷線jamica和斐濟

+0

閱讀關於線程優先級 – Vasco

+3

沒有guaranteee一個線程會後正好1000毫秒醒來取決於系統資源是否可用,可能需要更長的時間以及調度程序如何處理它。 – MartinS

+0

'System.out.println()'每次調用它需要不同的時間。 – Guy

回答

1

控制檯輸出不同步,因此它可能會在這種情況下,在封閉情況下的毛刺。 線程正在獲取以正確順序打印的命令,但打印本身需要不同的時間。

使主線程在啓動Jamica後睡10,並且會在兩個線程之間放置一段距離。

代碼示例:(建立在OP代碼):

class TwoThreadsTest extends Thread { // extends Thread addition 
    public static void main(String[] args) { 
     SimpleThread a = new SimpleThread("A"); 
     SimpleThread b = new SimpleThread("B"); 
     a.start(); 
     try { 
      sleep(10); // offsets Console Output de-synchronization 
     } catch (InterruptedException ex) { 
      // shouldn't happen 
     } 
     b.start(); 
    } 
} 

class SimpleThread extends Thread { 
    public SimpleThread(String str) { 
     super(str); 
    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      System.out.println(i + " " + getName()); 
      try { 
       sleep((int)(1000)); // (int) is redundant 
      } catch (InterruptedException e) {} 
     } 
     System.out.println("DONE! " + getName()); 
    } 
} 
+1

'main'中的睡眠會將'0 Jamaica'和'0 Fiji'之間的距離放在一起,但不能保證線程將交替打印。 – Guy

+0

@guy你是對的,但保證線程交替打印的方法需要通過wait \ sleep進行復雜的修改,同步線程或使用Concurrent庫。這裏的問題是控制檯輸出的非同步特性,而不是代碼。 –

+0

這不是「控制檯的性質」。這是應用程序代碼。控制檯輸出_is_同步,這就是輸出看起來不像「1 Jam2 Fiaijica」的原因。應用程序代碼是_not_ synchronized,這就是爲什麼當兩個線程競相調用'System.out.println()'時,獲勝者是不可預測的。 –