Java如何停止并发运行的线程

时间:2018-04-25 23:52:22

标签: java javafx text-to-speech java-threads

每当使用按钮从ActionEvent调用talk(String text,boolean voiceEnabled)方法时,我试图使文本到语音线程停止。

当按下这些按钮时,不同的文本字符串将传递给该方法,该方法在新线程上运行音频。如果当前线程仍在运行但是发生了新的ActionEvent,我需要停止当前线程(即文本到语音),以便可以在没有当前音频剪辑和新剪辑播放的情况下播放新的文本到语音音频在彼此的顶端。

这是我目前所拥有的,但TTS音频正在互相播放。一旦触发新的TTS,我需要当前的TTS停止。我相信我的主要问题是每次调用该方法时都会生成一个新的线程。

任何帮助非常感谢。谢谢!

public void talk(String text, boolean voiceEnabled) {
    System.out.println(text);

    // Create a new Thread as JLayer is running on the current Thread and will
    // make the application lag
    Thread thread = new Thread(() -> {
        try {
            // Create a JLayer instance
            AdvancedPlayer player = new AdvancedPlayer(synthesizer.getMP3Data(text));
            if (voiceEnabled) {
                player.play(); //Plays the TTS audio
                System.out.println("Successfully retrieved synthesizer data");
            }
            else {
            }
        } catch (IOException | JavaLayerException e) {

            e.printStackTrace();
        }
    });
    // We don't want the application to terminate before this Thread terminates
    thread.setDaemon(false);
    // Start the Thread
    thread.start();
}

1 个答案:

答案 0 :(得分:2)

您似乎在匿名内部类中隐藏了关键引用,并且我不知道如何在需要时如何访问它们。为什么这样?为什么不创建非匿名类的实例,一个具有AdvancedPlayer字段,一个引用由某个集合持有,可能是.stop()或HashMap,或者如果只有一到两个正在运行,在哪里可以提取对象,获取其AdvancedPlayer字段并在其上调用public class RunnablePlayer implements Runnable { private AdvancedPlayer player; private String text; private boolean voiceEnabled; public RunnablePlayer(String text, boolean voiceEnabled) { this.text = text; this.voiceEnabled = voiceEnabled; } @Override public void run() { try { // Create a JLayer instance player = new AdvancedPlayer(synthesizer.getMP3Data(text)); if (voiceEnabled) { player.play(); //Plays the TTS audio System.out.println("Successfully retrieved synthesizer data"); } } catch (IOException | JavaLayerException e) { e.printStackTrace(); } } public AdvancedPlayer getPlayer() { return player; } public void stop() { // perhaps do a null check here first? if (player != null) { player.stop(); } } }

如,

// field of the class
private RunnablePlayer runnablePlayer;

然后你可以有一个类的字段,如:

public void talk(String text, boolean voiceEnabled) {
    if (runnablePlayer != null) {
        runnablePlayer.stop();  // not calling this on a Thread
    }

    runnablePlayer = new RunnablePlayer(text, voiceEnabled);
    Thread thread = new Thread(runnablePlayer);
    //.....
    thread.start();
}

并在你的谈话方法中使用它:

#include <stdio.h>

unsigned long int fat(int a);
double sen(int n);
double coss(int n);

int main(void){
    int n;
    scanf("%d",&n);
    printf("%f %f\n",sen(n),coss(n));
    return 0;
}

unsigned long int fat(int a){
    unsigned long int x;
    if (a==0) return 1;
    else{
         for(x=1;a>0;a--) x=x*a;
         return x;
    }
}

double sen(int n){
    int x,i;
    double r;
    if(n==0) return 0;
    for(x=r=0,i=1;x<10;x++,i++){
         if(i==5) i=1;   
         if(i==1) r+=(sen(n-1))/(fat(x));
         if(i==2) r+=(coss(n-1))/(fat(x));
         if(i==3) r-=(sen(n-1))/(fat(x));
         if(i==4) r-=(coss(n-1))/(fat(x));
    }
    return r;
}

double coss(int n){
    int x,i;
    double r;
    if(n==0) return 1;
    for(x=r=0,i=1;x<10;x++,i++){
        if(i==5) i=1;   
        if(i==1) r+=(coss(n-1))/(fat(x));
        if(i==2) r-=(sen(n-1))/(fat(x));
        if(i==3) r-=(coss(n-1))/(fat(x));
        if(i==4) r+=(sen(n-1))/(fat(x));
    }
    return r;
}

代码未编译或测试,但只是提供一般概念。