Как получить доступ к выполняемому потоку/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% (на одно ядро) до разумного значения;)