2012-11-05 29 views
0

我在Java線程中觀察到一種奇怪的行爲,它們看起來以順序方式運行。以下是代碼段java中的線程以順序方式運行

class ThreadUnsafeClass { 

    private static int y; 

    public static void incrementY() { 
     y++; 
    } 

    public static int getY() { 
     return y; 
    } 

} 

public class MultiThreadedClass implements Runnable { 
    int threadId; 

    MultiThreadedClass (int threadId) { 
     this.threadId = threadId; 
    } 

    @Override 
    public void run() { 

     System.out.println("Number:"+ threadId + ";Thread Unsafe Old Value:" + ThreadUnsafeClass.getY()); 

     try { 
      if (threadId == 1 || threadId ==2) { 
       Thread.sleep(60000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     ThreadUnsafeClass.incrementY(); 

     System.out.println("Number:"+ threadId + ";Thread Unsafe New Value:" + ThreadUnsafeClass.getY()); 
    } 

    public static void main (String []args) { 
     MultiThreadedClass thread1 = new MultiThreadedClass(1); 
     MultiThreadedClass thread2 = new MultiThreadedClass(2); 
     MultiThreadedClass thread3 = new MultiThreadedClass(3); 
     MultiThreadedClass thread4 = new MultiThreadedClass(4); 
     thread1.run(); 
     thread2.run(); 
     thread3.run(); 
     thread4.run(); 
    } 
} 

以下是相同的輸出:

Number:1;Thread Unsafe Old Value:0 
Number:1;Thread Unsafe New Value:1 
Number:2;Thread Unsafe Old Value:1 
Number:2;Thread Unsafe New Value:2 
Number:3;Thread Unsafe Old Value:2 
Number:3;Thread Unsafe New Value:3 
Number:4;Thread Unsafe Old Value:3 
Number:4;Thread Unsafe New Value:4 

從上面的輸出,所以可以注意到,即使當線程1和2正在等待的合理量時間即60秒的線程3和4只有在執行完成後才能執行。爲什麼不是線程並行執行,並且當一個線程休眠時,爲什麼另一個線程沒有執行呢?我在哪裏錯了?

+0

不要你的意思是連續的,也不序列化? – mre

+0

你沒有啓動任何線程。 –

+0

你從未真正創建過任何線程!相反,在一個單獨的線程中,可以串行調用每個對象的「運行」功能! –

回答

6

您需要創建一個Thread,參考Runnable並調用start(),而不是run()實際的類。製作Runnable並不意味着它會自動在單獨的線程中運行。

例如

(new Thread(myRunnable)).start() 

爲什麼RunnableThread之間的距離?我可以採取Runnable並將其放入線程池中。下一個可用線程將運行Runnable。 (例如,參見Java Executor框架)Runnable僅指示對象可用於線程。

+0

感謝您的回答。我現在完全理解它。 –

3

由於thread1.run()同步調用方法,您應該擴展Thread並調用thread.start()而不是thread.run()thread.start將異步調用run(),實現您正在尋找的效果。

你也可以使用此構造構建從Runnable一個Thread

Thread(Runnable r)

+1

他們甚至不是線程。他們只是Runnable。 –

+0

@BrianAgnew感謝您的注意,我編輯了答案以反映它。 – dasblinkenlight

2

這是不夠的,必須落實到Runnable在不同的線程運行的類。取而代之的

MultiThreadedClass thread1 = new MultiThreadedClass(1); 
MultiThreadedClass thread2 = new MultiThreadedClass(2); 
MultiThreadedClass thread3 = new MultiThreadedClass(3); 
MultiThreadedClass thread4 = new MultiThreadedClass(4); 
thread1.run(); 
thread2.run(); 
thread3.run(); 
thread4.run(); 

嘗試做

new Thread(new MultiThreadedClass(1)).start(); 
new Thread(new MultiThreadedClass(2)).start(); 
new Thread(new MultiThreadedClass(3)).start(); 
new Thread(new MultiThreadedClass(4)).start(); 
+0

你沒有解釋_why_。 – Gray

+1

@Boris - 你的答案有一個小問題。由於MultiThreaded類不擴展Thread並僅實現Runnable接口,因此無法將Thread Class對象分配給MultiThreaded Class類型的變量。相應地修改你的答案。 –

+0

@AbhishekJain謝謝 –