2014-10-08 51 views
0

請在這方面給我一些生動的解釋。 我已經嘗試了很多,但我無法弄清楚。如果start()方法在它自己的body中調用,Thread程序中會發生什麼?

我完全搞砸了開始方法調用的代碼段,就像在下面的程序中重複調用一樣,甚至在進入開始方法體之前如何調用第一次啓動方法。

在此先感謝。

package appletexample; 
import java.awt.*; 
import java.applet.*; 
public class AppletOne extends Applet implements Runnable { 

    String str = "This is a simple Banner "; 
    Thread t ; 
    boolean b; 

    public void init() { 
      setBackground(Color.gray); 
      setForeground(Color.yellow); 
    } 

    public void start() { 
      t = new Thread(this); 
      b = false; 
      t.start(); 
    } 

    public void run() { 
      char ch; 
      for(; ;) { 
       try { 
        repaint(); 
        Thread.sleep(200); 
        ch = str.charAt(0); 
        str = str.substring(1, str.length()); 
        str = str + ch; 
       } catch(InterruptedException e) {} 
      } 
    } 

    public void paint(Graphics g) { 
      g.drawRect(1,1,300,150); 
      g.setColor(Color.yellow); 
      g.fillRect(1,1,300,150); 
      g.setColor(Color.red); 
      g.drawString(str, 1, 150); 
    } 
} 

即使是新手到線程的概念,請給我清楚的圖片相關。並給我一些參考網站,瞭解線程概念與小程序和基於Web的編程。

+0

這是什麼問題? – 2014-10-08 14:02:00

回答

3

你不能在已經啓動的線程上調用start() - 你會得到一個IllegalThreadStateException。但是,你的程序沒有這樣做。

在您的小程序的start方法中,創建Thread並將小程序本身作爲Runnable參數傳遞。這意味着當線程啓動時,它會調用小程序的run方法。然後你在線程上調用start()開始運行。但是你在線程上調用start(),而不是小程序,所以你不會不小心再次運行小程序自己的start方法。這裏沒有遞歸發生。


但是,您正在啓動一個線程並且從不停止它。那很糟。您的小程序需要自行清理並且不會讓該線程永久運行,即使小程序本身已經被銷燬。做到這一點的方法是:

首先,讓你的run方法實際上響應線程中斷。在您的catch (InterruptedException e)塊中,輸入return語句而不是忽略該異常。 (有關線程中斷的更多信息,請參見this article。)

其次,加stop()方法您的小程序 - 像start(),這是在Applet類中定義,當它的時間爲你的小程序,它會被自動調用停止。

第三,在您的新stop()方法中,請執行t.interrupt()後跟t.join()。這將告訴線程它應該停止運行,然後等待它來這樣做。

+0

是典型的/可以從後臺線程繪製小程序嗎? – Kevin 2014-10-08 14:06:34

+0

他應該使用applet的init方法,不是嗎? – UniversE 2014-10-08 14:08:29

+0

@Kevin,線程調用'repaint()',但那實際上不會立即執行繪畫;它只是要求UI線程儘快調用「paint」。我相信可以在非UI線程中調用repaint()。 – Wyzard 2014-10-08 14:13:26

0

下面的代碼段並不完全是最佳實踐,並且start()方法應該幾乎不會被覆蓋。

public void start() 
    { 
     t = new Thread(this); 
     b = false; 
     t.start(); 
    } 

重命名您的start()方法並在調用方法中調用它。

+0

不要混淆線程start()方法和Applet start()方法嗎? – UniversE 2014-10-08 14:04:16

+0

這不是_錯誤_,但確實造成了作者不完全理解如何創建和使用線程的錯覺。 – 2014-10-08 14:14:55

+0

確實..我出來的措辭有點太強大了。因爲人們很少需要重寫'start()' – 2014-10-08 14:16:11

相關問題