2011-04-06 45 views
9

我有一個線程正在運行,但從外部我無法繞過一個值來停止該線程。如何在Mytest()內發送錯誤/真值或調用正在運行的線程公共方法?當我按下按鈕1? 例如:thread.interrupt();runnable.stop();runnable.start();如何訪問正在運行的線程/ runnable?

// Main 
public class Main extends JFrame 
{ 
    public static Runnable runnable; 
    public static Thread thread; 
    private JButton b1 = new JButton("Start/Stop"); 

    public void init() 
    {  
    //Execute a job on the event-dispatching thread: 
    try { 
     javax.swing.SwingUtilities.invokeAndWait(new Runnable() 
     { 
     public void run() 
     { 
      createGUI(); 
     } 
     }); 
    } catch (Exception e) { 
     System.err.println("createGUI didn't successfully complete"); 
    } 
    } 

    public void createGUI() 
    { 
    Container cp = getContentPane(); 
    b1.addActionListener(new button1()); cp.add(b1); 
    runnable = new Mytest(); 
    thread = new Thread(runnable); 
    thread.start(); 
    } 
} 

// Button 1 - [problem to go inside a running thread] 
public class button1 implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
    System.out.println("button pressed - need to access "); 
     //thread.interrupt();  runnable.stop(); //or runnable.start(); 
    } 
} 

// Running - Thread 
public class Mytest implements Runnable 
{ 
    public static boolean onoff = false; 
    public static boolean status = false; 

    public void run() 
    { 
    while(true) 
    { 
     if (onoff) 
     { 
     return; 
     } else { 
     if (status==false) System.out.println("running"); 
     } 
    } 
    } 
    public static void stop() { status = true; onoff=true; } 
    public static void start() { status = false; onoff = false; } 
} 

跟進(校對):

Step 1: 

/* Main - boot/startup */ 
public class Main extends JFrame 
{ 
    public static Mytest runnable; // wrong: public static Runnable runnable; 
    public static Thread thread; 
    private JButton b1 = new JButton("Start"); 
    private JButton b2 = new JButton("Stop"); 

    public void init() 
    {  
    // Execute a job on the event-dispatching thread: 
    // In case Freezed for heavy lifting 
    try { 
     javax.swing.SwingUtilities.invokeAndWait(new Runnable() 
     { 
     public void run() 
     { 
      createGUI(); 
     } 
     }); 
    } catch (Exception e) { 
     System.err.println("createGUI didn't successfully complete"); 
    } 
    } 

    public void createGUI() 
    { 
    Container cp = getContentPane(); 
    b1.addActionListener(new button1()); 
    cp.add(b1); 

    runnable = new Mytest(); 
    thread = new Thread(runnable);  
     try { 
       thread.sleep(100); // value is milliseconds   
       thread.start();  
     } catch (InterruptedException e) {    
     } 
    } 

    public static void main(String[] args) 
    {   
    run(new Main(), 500, 500); 
    } 

    public static void run(JFrame frame, int width, int height) 
    {  ... 
    frame.setVisible(true); 
    } 
} 

/* To start */ 
public class button1 implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
    runnable.start(); 
    }  
} 

/* To stop */ 
public class button2 implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
    runnable.stop(); 
    }  
} 

Step 2: 

/* Thread deals */ 
public class Mytest implements Runnable 
{ 
    private static volatile boolean running = true; 

    public void run() 
    { 
    while(running) 
    { 
     // do stuff 
    } 
    } 
    public void start() { running = true; } 
    public void stop() { running = false;} 
} 

回答

8

如果通過類,而不是作爲一個Runnable可以調用實例方法定義它。

public static Mytest runnable; 

另外要注意的是,由於多內核擁有自己相關的記憶,你需要提醒的是,國家可能會在另一個處理器更改的處理器,它需要留意是否有改變。聽起來很複雜,但只要加入「揮發」關鍵字布爾標誌

public class Mytest implements Runnable 
{ 
    private static volatile boolean running = true; 

    public void run() 
    { 
    while(running) { 
     // do stuff 
    } 
    } 

    public void stop() { running = false;} 
} 

啓動Runnable爲您最初的代碼,然後將其關閉使用runnable.stop()

+0

當runnable.stop()被調用時,它僅回採只在循環?但該實例仍未關閉?在這種代碼模式中?然後Thread.stop()或Thread.interrupt()需要殺死池? – YumYumYum 2011-04-06 07:51:49

+3

當'run'方法結束時,線程停止。如果需要,您可以將Mytest實例附加到新的線程,或者在現有線程上調用'start()',以便再次運行。此代碼只是確保運行代碼將在合理的時間範圍內完成(如果標誌不是不穩定的,則不是這種情況) – 2011-04-06 07:55:02

+0

Thanks!請參閱上面的最新更新。所以你的意思是,如果我們標記while循環來停止標誌,它會自動破壞線程,如果我們將它標記爲start(),它會重新創建線程? – YumYumYum 2011-04-06 08:15:19

1
從事實

除此之外,這個線程爲你的CPU發熱試驗;)

您可以調用start/stop方法與

MyThread.start(); 
MyThread.stop(); 

已將其定義爲static方法,所以上面的代碼行顯示如何調用它們。

用於加熱......添加類似

try { 
    Thread.sleep(100); // value is milliseconds 
} catch (InterruptedException e) { 
    // no need to handle (in this example) 
} 

這會從100%(在一個核心),減少CPU負荷爲合理值;)

2
運行中的方法

.. 。

不這樣做,而(真)..

使用布爾......像......而(threadIsRunning)

和這個布爾,你可以設置爲真/假....

+2

是的,但它必須是'AtomicBoolean',因爲a)它必須是final的; b)線程同步的保證方式 – 2011-04-06 07:30:47

3
 

public void run() 
    { 
    while(!isInterrupted()) { 
     if (onoff) { 
     return; 
     } else { 
     if (status==false) System.out.println("running"); 
     } 
    } 
    } 

 

然後使用了Thread.interrupt(),表示該線程的interrption。

注意:在任何情況下都不要使用Thread.stop()!這是已棄用
欲瞭解更多詳情,請參閱JDK文檔和< < Java Concurrency in Practice >>。

6

您應該始終使用中斷方法來停止線程。這是一種安全且適合執行線程停止操作的方式。

Thread tThread = new Thread(new Runnable() { 

       public void run() { 
         while (!Thread.currentThread().isInterrupted()) { 
         try{ 
         Thread.sleep(10); 
         ... do you stuff... 
         }catch(InterruptedException ex){ 

          break; 
         } 
        } 

       } 

      }); 
    tThread.start(); 

而當你想阻止你跟帖只是調用中斷方法:

tThread.interrupt(); 
+0

tThread.join();是阻止它的正確方法。它會等待任何睡眠或操作完成,以便在啓動時能夠重新創建。 – 2016-07-07 03:03:58