【问题标题】:Can no stop robot Thread无法停止机器人线程
【发布时间】:2015-06-29 03:36:35
【问题描述】:

我有一个线程,它有一个称为终止的布尔值 - 当它设置为 true 时,线程应该停止 - 问题是当我将它设置为 false 时它没有向线程注册?如何在我的线程中直接将终止的值设置为 true?谢谢

            btnPlayback.setOnMouseClicked(e -> {
            Playback function = new Playback(list, progBar, settings);
            Thread playback = new Thread(function);
            if (recording == true) {
                btnRecord.setText("Record");
                recording = false;
            }
            if (playing == false) {
                playing = true;
                btnPlayback.setText("Stop");
                playback.start();
            } else { 
                playing = false; 
                btnPlayback.setText("Playback");
                function.terminate();
            }
        }); 

这是在线程的类中

     public void terminate() {
         terminated = true;
    }

应该阻止这样的陈述

        for (InputValue i: list) {
            if (terminated == false) {

【问题讨论】:

  • terminated volatile?也许改用AtomicBoolean
  • 既然你说Threadterminate()的方法,那它可能不是function.terminate();而是playback.terminate();。否则很难解决问题,因为没有显示所有相关代码。

标签: java multithreading javafx


【解决方案1】:

假设

线程playback 负责在不同线程上播放媒体(无论键入什么)。下次请提供Minimal, Complete, and Verifiable example

问题

您使用 Thread 的 start 方法启动播放线程。这是正确的。但是您尝试通过调用 function.terminate() 来阻止它。由于我不完全了解 terminate() 的上下文,因此我无法在这里为您提供帮助,但更笼统地说。

一个更大的问题可能是,每次单击按钮时都会创建一个新线程和一个新播放对象。从下面的代码来看,这似乎是错误的。

解决方案

线程可以是interrupted!所以你需要说线程,如果有人点击“停止”按钮,中断它的工作并完成线程。

将 Thread 和 Playback 变量移到该块的外部。

在您的btnPlayback.setOnMouseClicked 方法中,对线程对象执行以下操作:

playback.interrupt();

但在 Runnable Playback 中,您必须注意中断。在您的 Runnable 中,您需要一些东西来证明标志中断状态,例如:

   if (Thread.interrupted()) {
      throw new InterruptedException();
    }

然后需要捕获异常,并且可以将您的终止设置为 true。因为没有更多的事情要做,运行可以返回:

  } catch (InterruptedException ex) {
    terminate = true;
    return;
  }

一个可能的解决方案如下所示。但是我不得不做出很多假设,因为您还没有完全清除。也许你想多读一点线程,然后访问这个教程:https://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;


public class JavaFXApplication8 extends Application {

  Playback function = null;
  Thread playback = null;

  @Override
  public void start(Stage primaryStage) {
    Button btn = new Button();
    btn.setOnAction((ActionEvent event) -> {
      if (function == null) {
        function = new Playback(list, progBar, settings);
      }
      if (playback == null) {
        playback = new Thread(function);
      }
      if (recording == true) {
        btnRecord.setText("Record");
        recording = false;
      }
      if (playing == false) {
        playing = true;
        btnPlayback.setText("Stop");
        playback.start();
      } else {
        playing = false;
        btnPlayback.setText("Playback");
        playback.interrupt();
        function = null;
        playback = null;
      }
    });

    StackPane root = new StackPane();
    root.getChildren().add(btn);
    Scene scene = new Scene(root, 300, 250);
    primaryStage.setTitle("Hello World!");
    primaryStage.setScene(scene);
    primaryStage.show();
  }

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
    launch(args);
  }

  static class Playback implements Runnable {

    boolean terminate = false;

    @Override
    public void run() {
      try {
        // playing music or something else and ask sometimes, if this is interrupted
        if (Thread.interrupted()) {
          throw new InterruptedException();
        }
      } catch (InterruptedException ex) {
        terminate = true;
        return;
      }
    }

  }
}

【讨论】:

    猜你喜欢
    • 2021-06-28
    • 2013-04-18
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2012-01-14
    • 2014-08-31
    • 1970-01-01
    相关资源
    最近更新 更多