Как получить доступ к выполняемому потоку/runnable?

У меня есть поток, но извне я не могу обойти значение, чтобы остановить этот поток. Как я могу отправить значение false/true внутри Mytest() или вызвать текущие общедоступные методы потока? Когда я нажимаю кнопку1? ex: thread.interrupt(); runnable.stop(); или runnable.start();

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

Ответ 1

если вы определяете его по классу, а не как Runnable, вы можете вызвать методы экземпляра.

public static Mytest runnable;

Также обратите внимание, что из-за того, что несколько ядер имеют свою собственную связанную память, вам необходимо предупредить процессор о том, что состояние может быть изменено на другом процессоре и что ему нужно следить за этим изменением. Звучит сложно, но просто добавьте ключевое слово volatile для булевых флагов

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

Ответ 2

Вы всегда должны использовать метод прерывания для остановки потока. Это безопасный и адекватный способ выполнения операции остановки нитью.

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

Ответ 3


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


Затем используйте Thread.interrupt(), чтобы указать перемещение потока.

Примечание: Не используйте Thread.stop() ни при каких обстоятельствах! Он Устаревший!
Более подробно документ JDK и < Java Concurrency in Practice → можно называть.

Ответ 4

в вашем методе запуска...

dont do while (true)..

используйте boolean... like... while (threadIsRunning)

и это логическое значение вы можете установить в true/false....

Ответ 5

Помимо того, что этот поток является тестом на нагрев вашего процессора;)

Вы можете вызвать методы старт/стоп с помощью

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

Вы определили их как методы static, поэтому приведенные выше строки кода показывают, как их вызвать.

для нагрева... добавьте что-то вроде

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

Это уменьшит нагрузку процессора с 100% (на одно ядро) до разумного значения;)