2013-06-04 38 views
1

我剛開始使用線程。我寫的建立和啓動100個線程,一個主類等待5秒鐘,然後中斷他們(至少這是我認爲它所做的那樣):如何(可靠地)中斷線程在Java中的特定時間之後形成主線程?

public static void main(String[] args) { 

    List<Thread> threads = new ArrayList<Thread>(); 

    for (int i = 0; i < 100; i++) { 
     Thread t = new Thread(new Walker()); 
     threads.add(t); 
    } 

    System.out.println("Starting threads..."); 

    for (Thread thread : threads) { 
     thread.start(); 
    } 

    try { 
     Thread.sleep(5000); 
    } catch (InterruptedException e) { 
     // don't do anything 
    } 

    System.out.println("Time's up - Terminating threads..."); 
    for (Thread t : threads) { 
     t.interrupt(); 
     System.out.print("."); 
    } 
    for (Thread t : threads) { 
     try { 
      t.join(10); 
     } catch (InterruptedException e) { 
      // don't do anything 
     } 
    } 
    System.out.println(""); 
    System.out.println("All done."); 
} 

螺紋看上去有點像這樣:

public class Walker implements Runnable { 
    public void run() { 
     for (int i = 0;; i++) { 
      //do some complicated stuff that takes some time 
      System.out.println(Thread.currentThread().getName() + ":" + i); 
      if (Thread.interrupted()) { 
       break; 
      } 
     } 
    } 
} 

現在,我得到的輸出是主線程開始中斷線程,但是一些子線程在終止之前繼續運行幾次(即循環迭代),例如

啓動線程...
線程1:0
線程2:0
線程1:1
線程3:0
[...]
時間到了 - 終止線程...
......線程1:60
線程1:61
...螺紋-1:62
線程2:55
..所有完成。
[從線程輸出有時甚至繼續在​​這裏 - 聯接()之後 - 我的預期

當時我沒有完全明白,一個線程可以分配足夠的處理器時間來運行幾次在主線程有機會中斷它之前至多再運行一次。

不過,雖然我現在看,這是絕對的罰款吧,我還是想知道一些(長)時間的主線程都有機會結束前(即中斷)要執行的線程:有一個容易方式從主線程及時中斷所有子線程? (通過線程的構造函數設置「生存時間」,然後在Walker類中進行測試,這不是我想要的。)

另請參見:是否有可能執行最後一個print語句,然後查看一些輸出個人線程 - 畢竟線程被加入()編輯? (也許我有毛刺其它地方;實際的代碼更復雜一點......)

回答

1

你觀察到的問題很可能是由於如何System.out.println作品。這是一種同步方法。因此,一個可能的解釋是:

  • 調用t.interrupt();System.out.print(".");時,釋放鎖定之前,你的主線程獲取鎖打印
  • ,工作線程到達System.out.println(Thread.currentThread().getName() + ":" + i);和等待鎖定
  • 當主線程釋放鎖,所有正在等待的工作線程都會打印其進度。
  • 主線程到達System.out.print(".");一次必須等待打印鎖可用於等

關於這個事實,你看到更多的打印從工作線程打印"All Done"後:你只join 10毫秒,所以它可能是不夠的,並且一個線程在被中斷10毫秒內沒有完成。如果你只是使用join()你不應該再看到。再現行爲Worker類的

例如,你觀察:

class Walker implements Runnable { 

    public void run() { 
     for (int i = 0;; i++) { 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException ex) { 
       //do not respond to interruption too quickly on purpose 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) {} 
       Thread.currentThread().interrupt(); 
      } 
      System.out.println(Thread.currentThread().getName() + ":" + i); 
      if (Thread.interrupted()) { 
       break; 
      } 
     } 
    } 
} 
0
Maybe I have a glitch somewhere else; the actual code is a bit more complex... 

是的,它是一個小故障,不幸的是,不是一個簡單的一套房產,Java方面。

如果代碼是商業的,複雜的,比您可以分配更多時間來編寫一些本地庫,對於主要的Os類型。有了這個幫助,你可以很容易地玩你想要的線程。

第一時間擁有開發和如何理解線程沃金在本機,操作系統方面的開銷,不僅僅是調用函數與幾個PARAMS :)

不知道,如果是幫助,毛刺存在。

2

這將是與ExecutorService的更容易,如

int nThreads = 100; 
    ExecutorService ex = Executors.newFixedThreadPool(nThreads); 
    for (int i = 0; i < nThreads; i++) { 
     ex.execute(new Walker()); 
    } 
    Thread.sleep(5000); 
    ex.shutdownNow(); 
+0

謝謝你,我會在一個去。 :) – Christian