2015-12-23 62 views
2

我是java新手,我正在嘗試瞭解線程。我期待hello this is thread onehello this is thread two的輸出。但我得到的輸出如下:如何在java中同時運行兩個線程

hello this is thread one 
hello this is thread one 
hello this is thread one 
hello this is thread one 
hello this is thread one 
hello this is thread two 
hello this is thread two 
hello this is thread two 
hello this is thread two 
hello this is thread two 

以下是我的代碼。任何人都可以請幫助我爲什麼我得到這個輸出,而不是預期的。我能做什麼來並行運行兩個線程。

public class ThreadDemo { 
    public static void main(String args[]) { 

     // This is the first block of code 
     Thread thread = new Thread() { 
      public void run() { 
       for (int i = 0; i < 10; i += 2) { 
        System.out.println("hello this is thread one"); 
       } 
      } 
     }; 

     // This is the second block of code 
     Thread threadTwo = new Thread() { 
      public void run() { 
       for (int i = 0; i < 10; i += 2) { 
        System.out.println("hello this is thread two"); 
       } 
      } 
     }; 

     // These two statements are in the main method and begin the two 
     // threads. 
     // This is the third block of code 
     thread.start(); 

     // This is the fourth block of code 
     threadTwo.start(); 
    } 
} 
+2

只是循環,直到你的線程100,你會看到一些備用輸出 –

+0

看這個http://stackoverflow.com/questions/13263079/run - 兩個線程在最相同的時間,在Java的。 – iCroque

+0

@GerardRozsavolgyi它可能會做,但不一定。因爲它正在做一件非常簡單的事情,所以第一個線程的執行可能總是在第二個線程被調度之前完成。 –

回答

1

您的代碼也可以工作..在第一個對象中加入睡眠。

// This is the first block of code 
     Thread thread = new Thread() { 
      public void run() { 
       for (int i = 0; i < 10; i += 2) { 
        System.out.println("hello this is thread one"); 
        try { 
         sleep(100); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 

     }; 
2

根據CPU和/或CPU內核的數量,多線程只能由你的CPU通過爲每個線程一定數量的時間另一個線程被調度之前模擬。另請參見Wikipedia on "Preemptive Multitasking"

此外,考慮到今天的CPU和許多內核及其速度,也可能是在第二個線程啓動之前第一個線程的執行已經完成。

另外,兩個線程都在爲System.out中的鎖進行爭奪,因此它們將互相鎖定。

讓線程運行更長的時間(更高的迭代次數),您將看到您期待的交織。

+1

「線程之戰」 - 「誰將贏得'System.out'? – Emz

3

只是因爲線程可能交錯並不意味着他們。你的線程運行速度太快。嘗試添加Thread.sleep()以使它們運行更長時間。

2

這裏的問題是PrintStream是​​這是不公平的。

final Lock lock = new ReentrantLock(true); //create fair lock 
         //after running this code change it to 
         //ReentrantLock(false); to see what happens 

    // This is the first block of code 
    Thread thread = new Thread() { 
     public void run() { 
      for (int i = 0; i < 10; i += 2) { 
       lock.lock(); 
       System.out.println("hello this is thread one"); 
       lock.unlock(); 
      } 
     } 

    }; 

    // This is the second block of code 
    Thread threadTwo = new Thread() { 
     public void run() { 
      for (int i = 0; i < 10; i += 2) { 
       lock.lock(); 
       System.out.println("hello this is thread two"); 
       lock.unlock(); 
      } 
     } 

    }; 

    // These two statements are in the main method and begin the two 
    // threads. 
    // This is the third block of code 
    thread.start(); 

    // This is the fourth block of code 
    threadTwo.start(); 

當鎖定是公平這將是慢了很多,但是當它的不公平在你的第一個情況下,它保持遍地抓鎖的其他線程都有機會把它之前。公平的鎖就像一個隊列。誰排隊接下來獲得它。

+0

謝謝!」鎖定「這一點使得它更加清晰 – asgs

0

您的代碼按預期工作,絕對不能保證您的實現將以您預期的預定義方式執行。

我建議你看看實現多線程代碼的其他方法,如join(),sleep()以及找到更適合你的需求的方法。

+1

」您的代碼按預期工作「當然,只要您期待實際的行爲,代碼往往會這樣做。 –

0

如果你想有螺紋的屍體等待兩個線程在運行,你可以使用像一個CountDownLatch,它可以阻止,直到它的內部計數器計數下降到零:

final CountDownLatch latch = new CountDownLatch(2); 
Thread thread = new Thread() { 
    @Override public void run() { 
    latch.countDown(); 
    latch.await(); // Execution waits here until latch reaches zero. 

    // Rest of the method. 
    } 
} 
Thread threadTwo = new Thread() { 
    @Override public void run() { 
    latch.countDown(); 
    latch.await(); // Execution waits here until latch reaches zero. 

    // Rest of the method. 
    } 
} 

thread.start(); 
threadTwo.start(); 

(異常處理爲了清楚起見省略)

這將保證兩個線程的運行方法的「有趣位」將同時執行。然而,由於對println()方法,你所呼叫的不公平同步的,不存在由兩個線程打印的信息將如何交錯保證:

  • 有時,他們可能會「完全」交錯(1,2, 1,2,...)
  • 有時候可能會打印一些沒有任何其他的東西(1,1,2,2,2,2,2,...)
  • 有時可能會打印所有的消息在另一個之前(1,1,1,1,2,2,2,2)。
0

下面代碼工作...

public class ThreadDemo { 

    public static void main(String args[]) throws InterruptedException { 

     // This is the first block of code 
     Thread thread = new Thread() { 
      public void run() { 
       for (int i = 0; i < 10; i += 2) { 
        System.out.println("hello this is thread one"); 
        try { 
         Thread.sleep(100); 
        } catch (InterruptedException ex) { 
         Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex); 
        } 
       } 
      } 
     }; 

     // This is the second block of code 
     Thread threadTwo = new Thread() { 
      public void run() { 
       for (int i = 0; i < 10; i += 2) { 
        System.out.println("hello this is thread two"); 
        try { 
         Thread.sleep(100); 
        } catch (InterruptedException ex) { 
         Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex); 
        } 
       } 
      } 
     }; 

     // These two statements are in the main method and begin the two 
     // threads. 
     // This is the third block of code 
     thread.start(); 

     // This is the fourth block of code 
     threadTwo.start(); 

    } 
}