2011-04-06 18 views
9

Tengo un hilo ejecutándose pero desde afuera no puedo omitir un valor para detener ese hilo. ¿Cómo puedo enviar valores falsos/verdaderos dentro de Mytest() o llamar a los métodos públicos de ejecución de hilos? Cuando presiono el botón1? ejemplo: thread.interrupt();runnable.stop(); o runnable.start();¿Cómo acceder al hilo en ejecución/ejecutable?

// 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; } 
} 

seguimiento (leer la prueba):

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;} 
} 

Respuesta

8

si se define por clase en lugar de como un Runnable puede llamar a los métodos de instancia.

public static Mytest runnable; 

También tenga en cuenta que, debido a los múltiples núcleos que tienen su propia memoria asociada, es necesario advertir al procesador que el estado puede ser cambiado en otro procesador y que tiene que ver para ese cambio. Suena complicado, pero sólo tiene que añadir la palabra clave 'volátil' a las banderas booleanas

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

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

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

Iniciar el Runnable como en su código inicial, luego apagarlo mediante runnable.stop()

+0

Cuando runnable.stop() se llama, es que Stoping Sólo el bucle? Pero la instancia aún no está cerrada? En este patrón de código? Entonces Thread.stop() o Thread.interrupt() requiere matar el grupo? – YumYumYum

+3

el hilo se detiene cuando el método 'run' finaliza. Si es necesario, puede adjuntar la instancia de Mytest a un nuevo hilo o invocar 'start()' en el hilo existente si desea ejecutarlo nuevamente. Este código solo se asegura de que el código de ejecución se complete dentro de un marco de tiempo razonable (que no es el caso si la bandera no es volátil) –

+0

¡¡Gracias !! Por favor, mira la última actualización anterior. Entonces, ¿quieres decir que si marcamos el bucle while para detener el indicador, automáticamente se destruye el hilo, y si lo marcamos para iniciar(), se vuelve a crear el hilo? – YumYumYum

1

Aparte del hecho de que este hilo es una prueba de calentamiento para su CPU;)

puede llamar al arranque/parada con métodos

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

Usted los ha definido como 012.métodos, por lo que las líneas de código anteriores muestran cómo llamarlos.

para la calefacción ... añadir algo como

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

Esto reducirá la carga de la CPU del 100% (en un núcleo) a un valor razonable;)

2

en su método run .. .

No hago los while (true) ..

usar un valor lógico ... como ... mientras que (threadIsRunning)

y esto booleano puede establecer a verdadero/falso ....

+2

Es cierto, pero tendrá que ser un 'AtomicBoolean' porque a) tendrá que ser final y b) de esa manera la sincronización de hilos está garantizada –

3
 

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

 

A continuación, utilice Thread.interrupt() para indicar una interrption de la rosca.

Nota: No utilice Thread.stop() bajo ninguna circunstancia! Es Deprecated!
Para obtener más detalles, se puede consultar el documento JDK y < < Java Concurrency in Practice >>.

6

Siempre debe usar el método de interrupción para detener un hilo. Esta es una forma segura y adecuada de realizar una operación de detención y un hilo.

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(); 

Y cuando se quiere dejar de enhebrar simplemente invoca el método de interrupción:

tThread.interrupt(); 
+0

tThread.join(); es la forma correcta de detenerlo. Esperará a que finalice cualquier operación u operaciones para que pueda recrearse nuevamente cuando la inicie. –

Cuestiones relacionadas