在java中尝试停止多个线程中的一个线程同时运行
所以当我有多个线程运行时,我试图停止一个线程,下面是我用来初始化线程的代码。基本上,我在javafx中有多个文本字段,当在屏幕上单击一个按钮时,它会用递增计时器逐个填充文本字段。现在,我还为每个文本字段设置了一个按钮来清除它,但问题是当我清除它时,因为线程仍在运行,计时器会消失一秒钟,然后返回,因为行“orderTimes.getboxNo.setTextminute+second;”在代码中 现在我试着创建一个线程列表,我试着在下面实现它,但它不起作用,因此,如果单击了每个线程的清除按钮,我可以调用每个线程 有人知道我如何在正在运行的多个线程中只关闭/停止一个线程吗?如果需要更多信息,请告诉我,谢谢在java中尝试停止多个线程中的一个线程同时运行,java,multithreading,javafx,textfield,java-threads,Java,Multithreading,Javafx,Textfield,Java Threads,所以当我有多个线程运行时,我试图停止一个线程,下面是我用来初始化线程的代码。基本上,我在javafx中有多个文本字段,当在屏幕上单击一个按钮时,它会用递增计时器逐个填充文本字段。现在,我还为每个文本字段设置了一个按钮来清除它,但问题是当我清除它时,因为线程仍在运行,计时器会消失一秒钟,然后返回,因为行“orderTimes.getboxNo.setTextminute+second;”在代码中 现在我试着创建一个线程列表,我试着在下面实现它,但它不起作用,因此,如果单击了每个线程的清除按钮,我可
public static void createIncrementingTimer(int boxNo, List<TextField> orderTimes) {
minutesList.set(boxNo, 0);
secondsList.set(boxNo, 0);
state = true;
new Thread(threadList.get(boxNo)) {
int currentMinutes = 0;
int currentSeconds = 0;
public void run() {
for (;;) {
if (state = true) {
try {
sleep(1000);
if (secondsList.get(boxNo) > 59) {
secondsList.set(boxNo, 0);
currentSeconds = 0;
minutesList.set(boxNo, currentMinutes + 1);
currentMinutes++;
}
if (secondsList.get(boxNo) < 10) {
second = ":0" + Integer.toString(secondsList.get(boxNo));
} else {
second = ":" + Integer.toString(secondsList.get(boxNo));
}
secondsList.set(boxNo, currentSeconds + 1);
currentSeconds++;
if (minutesList.get(boxNo) < 10) {
minute = "0" + Integer.toString(minutesList.get(boxNo));
} else {
minute = Integer.toString(minutesList.get(boxNo));
}
orderTimes.get(boxNo).setText(minute + second);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
threadList.get(boxNo).start();
}
下面是我用来清除文本字段的代码,orderTimes是我试图清除的文本字段列表
public static void eraseBox(int clickedButtonNumber, List<TextArea> orderContentsList, List<TextField> tableNumbers, List<TextField> orderNumbers, List<TextField> orderTimes) {
orderContentsList.get(clickedButtonNumber).setText(null);
tableNumbers.get(clickedButtonNumber).clear();
orderNumbers.get(clickedButtonNumber).clear();
orderTimes.get(clickedButtonNumber).clear();
}
我建议你尽量避免线程。动画API旨在使通常在线程中完成的工作变得更容易。在本例中,IncrementingTimer类由两个标签和三个按钮组成。标签用于显示时间。这些按钮用于控制时间线。时间线用于每秒或每六十秒增加标签值。我在应用程序中添加了三个递增时间 主要 递增时间 ifstate=true应该是ifstate==true或者只是ifstate,但实际上for;;可以按照whilestate完成整个任务,只需在设置state=false时关闭线程 然后,当state=false时,可能会完全停止线程;threadList.getboxNo.join;,只有在这之后才能清除字段,因为线程也会在最后一步中将其设置为某个值 使用一种更简单的方法,您可以放弃状态,并恢复为;;,在圈外进行尝试捕捉的扭转。这样就可以使用threadList.getboxNo.interrupt;threadList.getboxNo;。参加要停止线程,最重要的是它将立即停止,因为当线程被中断时睡眠将立即结束。按照Sedric的建议,使用JavaFx动画工具进行计数器。 下面的一个文件演示了使用两种不同的动画工具实现计数器。 其中一个使用PauseTransition和Timeline,每个都有停止按钮。 将整个代码复制粘贴到Timers.java并运行
您可以拥有String和Thread类型的HashMap,然后,当您按下cancel按钮时,您可以使用HashMap解析正确的线程,您可以取消/杀死该线程。该线程需要知道您正在尝试停止它。现在不是。如果你使用JavaFX,你应该尽量避免使用线程。在很多情况下,您可以使用动画API中的东西来更好地完成这些任务。。在线程中,将导致不可预测的代码,并极有可能导致冻结。将该代码包装在Platform.runLater->{//code Here!};一个更简洁的小建议是:getChildren.addAllbtnPlay、btnPause、btnStop、lblMinutes、lblColon、lblSeconds;我会努力让它工作,理论上它看起来应该是好的,只需要一些改变,但会在一点点后回复你,谢谢!嘿,我不太确定如何在我当前的代码中实现这一点,因为我为每个计时器使用textFields,而我显然不能为timeline对象使用.setText。有没有其他方法来设置当前文本字段以包含分钟和秒?我的程序有时间线,因此它能够检测单击哪个按钮并停止计时器。谢谢我用scenebuilder来制作我的ui,而不是自己编写,所以用我目前拥有的来实现它可能有点困难,可以先尝试动画api,如果我有问题,我会尝试这个,谢谢!您可以在fxml中使用计数器和计数器。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
/**
* JavaFX App
*/
public class App extends Application {
@Override
public void start(Stage stage) {
var scene = new Scene(new VBox(new IncrementingTimer(), new IncrementingTimer(), new IncrementingTimer()), 640, 480);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.util.Duration;
/**
*
* @author blj0011
*/
final public class IncrementingTimer extends HBox
{
IntegerProperty secondsCounter = new SimpleIntegerProperty();//Keeps up with seconds
IntegerProperty minutesCounter = new SimpleIntegerProperty();//Keeps up with minutes
Label lblSeconds = new Label();//Displays the seconds
Label lblMinutes = new Label();//Displays the minutes
Label lblColon = new Label(":");//Display the colon between minutes and seconds
Button btnPlay = new Button("Play");//Plays the Timeline
Button btnStop = new Button("Stop");//Stops the Timeline
Button btnPause = new Button("Pause");//Pauses the Timeline
Timeline timeline;//Used to run code that changes the Labels. This Timeline runs every one second.
public IncrementingTimer()
{
lblSeconds.textProperty().bind(secondsCounter.asString("%02d"));//Binds the seconds label to the seconds counter. Sets the String to always show two digits. Exmaple 1 is shown as 01.
lblMinutes.textProperty().bind(minutesCounter.asString("%02d"));//Binds the minutes label to the minutes counter. Sets the String to always show two digits. Exmaple 1 is shown as 01.
getChildren().addAll(lblMinutes, lblColon, lblSeconds, btnPlay, btnStop, btnPause);
timeline = new Timeline(new KeyFrame(Duration.seconds(1), (event) -> {//Replace the one with .016 to speed this up for testing purposes.
secondsCounter.set(secondsCounter.get() + 1);
if (secondsCounter.get() == 60) {
secondsCounter.set(0);
minutesCounter.set(minutesCounter.get() + 1);
if (minutesCounter.get() == 60) {
minutesCounter.set(0);
}
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);
btnPlay.setOnAction((event) -> {
timeline.play();
});
btnPause.setOnAction((event) -> {
timeline.pause();
});
btnStop.setOnAction((event) -> {
timeline.stop();
secondsCounter.set(0);
minutesCounter.set(0);
});
this.setAlignment(Pos.CENTER);
}
}
import java.io.IOException;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.PauseTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Timers extends Application {
@Override public void start(final Stage stage) throws IOException {
VBox root = new VBox(new CounterPane(new TimeLineCounter()), new CounterPane(new PauseTransitionCounter()));
stage.setScene(new Scene(root));
stage.show();
}
public static void main(final String[] args) { launch(args); }
}
class CounterPane extends HBox{
private final Counter counter;
CounterPane(Counter counter) {
super(5);
this.counter = counter; //todo: check not null
Button stopBtn = new Button("Stop");
stopBtn.setOnAction(e->stop());
getChildren().addAll(stopBtn, counter);
}
void stop(){
counter.getAnimation().stop();
}
}
abstract class Counter extends Label {
protected int count = 0;
public Counter() {
setAlignment(Pos.CENTER); setPrefSize(25, 25);
count();
}
abstract void count();
abstract Animation getAnimation();
}
class TimeLineCounter extends Counter {
private Timeline timeline;
@Override
void count() {
timeline = new Timeline();
timeline.setCycleCount(Animation.INDEFINITE);
final KeyFrame keyFrame = new KeyFrame(
Duration.seconds(1),
event -> { setText(String.valueOf(count++) ); }
);
timeline.getKeyFrames().add(keyFrame);
timeline.play();
}
@Override
Animation getAnimation() {
return timeline;
}
}
class PauseTransitionCounter extends Counter {
private PauseTransition pauseTransition;
@Override
void count() {
pauseTransition = new PauseTransition(Duration.seconds(1));
pauseTransition.setOnFinished(event ->{
setText(String.valueOf(count++) );
pauseTransition.play();
});
pauseTransition.play();
}
@Override
Animation getAnimation() {
return pauseTransition;
}
}