2011-04-06 50 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