基本上,我有一个名为Playback的类,它扩展了一个线程。我希望能够从我的线程对象中运行我从此类定义的函数,但是当我这样做时,它们对所述对象的当前线程没有影响。我只能调用我的函数,如果我是.run()而不是.start(),但这会导致我的GUI冻结。这是我的代码
Playback function = new Playback(list, progBar, settings);
function.start();
function.terminate();
以上代码不起作用,但以下代码
Playback function = new Playback(list, progBar, settings);
function.run()
function.terminate();
当我使用run但它会导致我的GUI冻结。如何在已经运行的线程上调用我的方法?
答案 0 :(得分:0)
这是我的播放课程:
package chronos.Functions;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.util.List;
import javafx.scene.control.ProgressBar;
import chronos.Graphics.InputValue;
public class Playback extends Thread {
List<InputValue> list;
ProgressBar progBar;
Settings settings;
boolean terminated = false;
public Playback(List<InputValue> list, ProgressBar progBar, Settings settings) {
this.list = list;
this.progBar = progBar;
this.settings = settings;
}
public void run() {
try {
Robot bot = new Robot();
double x = settings.getCycleNumbers();
Thread.sleep(settings.initialDelay);
for (double c = 0; c <= x; c++) {
if (terminated == false) {
System.out.println(terminated);
System.out.println(isInterrupted());
progBar.setProgress(c/x);
if (list.isEmpty() != true) {
for (InputValue i: list) {
if (terminated == false) {
if (i.getType() == "key") {
long longRuntime = System.currentTimeMillis();
if (settings.recDurations == true) {
if (i.getDuration() > 0) {
while(i.getDuration() > System.currentTimeMillis() - longRuntime ) {
bot.keyPress(i.getCode());
}
} else {
bot.keyPress(i.getCode());
}
} else {
if (settings.getDurationTime() > 0) {
while(settings.getDurationTime() > System.currentTimeMillis() - longRuntime ) {
bot.keyPress(i.getCode());
}
} else {
bot.keyPress(i.getCode());
}
}
} else {
bot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
if (settings.recDurations == true) {
Thread.sleep(i.getDuration());
} else {
Thread.sleep(settings.getDurationTime());
}
bot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
if (settings.recPositions == true) {
bot.mouseMove(i.getX(), i.getY());
}
}
if (settings.trackDelay == true) {
Thread.sleep(i.getDelay());
} else {
Thread.sleep(settings.getKeyDelay());
}
} else {
break;
}
Thread.sleep(settings.cycleDelay);
}
} else {
progBar.setProgress(0);
}
} else {
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void terminate() {
System.out.println("terminated");
terminated = true;
}
}
答案 1 :(得分:0)
如何在已经运行的线程上调用我的方法?
你不能。
一个线程执行其run()
方法的功能。没有办法改变这一点。如果你想让一个线程做某件事,那么你必须使用run()方法来创建它。
请记住,run()方法可以做什么没有限制。例如,它可能会在BlockingQueue上等待“命令”对象,并且每次获取命令时,它都可能“执行”该命令。在这种情况下,run()方法可以执行尽可能多的“不同的事情”,因为您可以传递给它的不同命令对象。
答案 2 :(得分:0)
您的线程没有终止,因为您没有正确同步对terminate
变量的访问:一个线程修改它,另一个线程读取它。
如果它至少不是易失性的,那么Java内存模型并不能保证一个线程所做的修改是从另一个线程可见的。
因此,要么声明你的变量volatile
,要么使用AtomicBoolean,或者使用允许中断线程的本机机制:调用thread.interrupt()让它停止,并检查Thread.currentThread().isInterrupted()在循环中检查线程是否必须停止。
使用中断的好处是线程在能够停止之前不会等待sleep()
返回。相反,sleep()
(以及其他阻塞方法)将立即抛出InterruptedException,通知您线程已被要求停止。