2012-01-15 60 views
1

我沒有完全理解線程的概念我有一些問題。假設我們有下面的代碼:線程完成時檢查執行代碼

ExecCommand.java

// I don't know how this work, for now 
package therads; 

// Here we will have the methods and run them from the Main.java 
public class ExecCommand implements Runnable 
{ 
    String name; 
    int time; 

    public ExecCommand(String s,int amount) 
    { 
     name = s; 
     time = amount; 
    } 

    // Run method (Runnable) 
    public void run() 
    { 
     try 
     { 
      // What to execute when the thread is started 
      System.out.printf("%s is sleeping for %d\n",name,time); 
      Thread.sleep(time); 
      System.out.printf("%s is done\n",name); 
     } 
     catch(Exception e) 
     { 

     } 
    } 

    // This dosen't work when the thread is stopped 
    public void stop() 
    { 
     try 
     { 
      System.out.printf("STOPPED!"); 
     } 
     catch(Exception e) 
     { 

     } 
    } 

    // This dosen't work when the thread is started 
    public void start() 
    { 
     try 
     { 
      System.out.printf("Started!"); 
     } 
     catch(Exception e) 
     { 

     } 

    } 
} 

,我叫他從:

Main.java

Thread t5 = new Thread(new ExecCommand("Good Function",1000)); 
t5.start(); 
  1. 我想到println()線程啓動時「開始」,完成時「停止」。有可能的?

  2. 當線程完成時,它死了,完全從內存中釋放出來?如果沒有,我該怎麼做?

  3. 我該如何製作一個線程,每1000個毫秒重複一次,直到我按下一個鍵?我在想while(true) { t5.start; }

,但我不知道。

回答

5

首先,使用startstop方法沒有意義。一切都發生在run方法中。

要在啓動和停止時打印消息,請將它們置於run方法的開始和結束處。無限循環,並繼續執行代碼,直到外部事件發生,使用標誌和循環就可以了:

class ThreadTask implements Runnable { 
    private volatile boolean flag = false; 

    public void setFlag(boolean value) { 
     flag = value; 
    } 

    public void run() { 
     System.out.println("Started"); 
     while(!flag) { 
      // execute code 
     } 
     System.out.println("Stopped"); 
    } 
} 

然後,當你想線程停止,只需設置標誌使用setFlag真。

是的,在run方法終止後,線程會被runtime + OS自動清除。

+0

我建議您在while循環中添加一個try {...} catch(InterruptedException e)(...},但這是它的jist。 – 2012-01-15 20:19:31

+0

謝謝,我會試試:) – Master345 2012-01-15 20:21:28

+0

它的工作原理完美地,我還添加了多少次重複線程 – Master345 2012-01-15 20:34:10

0

你不應該重寫啓動和停止方法。它們不是回調方法。

你想要的東西類似於SwingWorker類(假設你對UI相關的線程同步感興趣)。

如果不是,您可以自己繼承Thread並提供回調機制。

+0

那麼你是說沒有理由開始()和停止()? – Master345 2012-01-15 20:08:46

+0

啓動和停止方法應該由您調用。他們不是回調方法。 – 2012-01-15 21:04:35

3

爲什麼或什麼時候你會期望你的.start()和.stop()被調用? Runnable在界面中只有一個方法; 。跑()。 Thread的JavaDocs覆蓋了它非常好。 http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html。如果你想在線程啓動的時候發生某些事情,把那些東西放在你的.run()的頂部。如果你想在線程完成時發生什麼事情,把它放在.run()的底部。不推薦使用線程上的.start()和.stop()方法執行任何操作。集中精力在你的.run()中完成你所有生命週期的事情。並獲得Goetz的「Java併發實踐」副本。它會告訴你全部的選項(包括你不直接擁有線程)。

+0

感謝你的回答,你在我腦海中製造了一個巨大的邏輯,但是你不認爲閱讀那本大書有點殘忍嗎?在YouTube上製作教程,這真的很有趣:D – Master345 2012-01-15 20:17:33

+0

@RowMinds。對於JCiP涵蓋的內容,它的確不是那麼大。讓線程錯誤會讓你的程序變得很糟糕,JCiP會把你的頭放在正確的地方去理解它是如何工作的,這會讓你無懼地使用它。如果您還發現了一些可以覆蓋它的視頻,那就去看看吧。一張圖片是千言萬語,對吧? – 2012-01-15 20:23:56

+0

你不是第一個這麼說的人,我想我必須閱讀,甚至有時候很艱難的閱讀有關編程,我寧願閱讀莎士比亞......但是如果必須這樣做,那就是了,謝謝:) – Master345 2012-01-15 20:33:33

0
  1. 當然可以。在run()方法的第一行,你可以只打印「開始」,並打印「停止」無論是在run()方法的finally部分或只是t5.join()
  2. 後,您並沒有被告知有關的細節,不能做任何事情。但你可以假設資源儘快被釋放。 (當然,如果你有你的線程中分配的任何引用可到達的鏈接,JVM不能決定,這些都是沒有用的,所以「完成」不是一個合適的詞在這裏。)
  3. 看看java.util.Timer
0
  1. 如果您更喜歡使用System.out.println而不是printf,只需更改這些代碼行即可。這些調用沒有任何線程相關。
  2. 當垃圾收集器停止運行並且沒有對其進行實時引用時,線程將被垃圾收集器從內存中收集和釋放。與所有對象相同。
  3. 請勿覆蓋stop()。這是deprecated,應該由JVM處理,而不是應用程序代碼。按照docs
  4. 只需覆蓋run即可執行任何您希望線程執行的操作。您可以使用Thread.sleep休眠一段時間。睡眠的準確程度將取決於您的平臺和可用系統時鐘的分辨率。