如何到达我的线程的运行实例?

时间:2015-06-29 17:11:39

标签: java multithreading class object

基本上,我有一个名为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冻结。如何在已经运行的线程上调用我的方法?

3 个答案:

答案 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,通知您线程已被要求停止。