简体   繁体   English

Java如何停止线程并发运行

[英]Java how to stop Threads running concurrently

I am trying to make a text to speech thread stop whenever the talk(String text, boolean voiceEnabled) method is called from an ActionEvent using buttons. 每当尝试使用按钮从ActionEvent调用talk(String text,boolean voiceEnabled)方法时,我都会尝试使文本到语音线程停止。

When these buttons are pressed different text Strings are passed to the method, which runs the audio on a new thread. 当按下这些按钮时,不同的文本字符串将传递给该方法,该方法将在新线程上运行音频。 If the current thread is still running but a new ActionEvent occurs I need the current thread to stop (ie the text-to-speech) so that the new text-to-speech audio can be played without the current audio clip and new clip playing over the top of eachother. 如果当前线程仍在运行,但是发生新的ActionEvent,则我需要当前线程停止(例如,文本到语音),以便可以在不播放当前音频片段和新片段的情况下播放新的文本到语音音频在彼此的顶部。

This is what I currently have but the TTS audio are playing over the top of eachother. 这是我目前拥有的,但是TTS音频在彼此的上方播放。 I need the current TTS to stop as soon as a new TTS is triggered. 我需要当前的TTS在触发新的TTS后立即停止。 I believe my main problem is that a new Thread is being made each time the method is called. 我相信我的主要问题是每次调用该方法时都会创建一个新的线程。

Any help greatly appreciated. 任何帮助,不胜感激。 Thanks! 谢谢!

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();
}

You appear to be burying key references inside of anonymous inner classes, and I don't see how you can get to them when and if needed. 您似乎正在将关键引用隐藏在匿名内部类中,并且我看不到如何以及何时需要它们。 Why do this? 为什么这样 Why not create an instance of a non-anonymous class, one with an AdvancedPlayer field, one whose reference is held by some collection, perhaps a List<...> or a HashMap, or by a variable if only one to two are running, where you can extract the object, get its AdvancedPlayer field and call .stop() on it? 为什么不创建一个非匿名类的实例,一个带有AdvancedPlayer字段的实例,一个实例的引用由某个集合(也许是List<...>或HashMap)保存,或者如果只运行一到两个,则由变量保存,您可以在其中提取对象,获取其AdvancedPlayer字段并在其上调用.stop()

eg, 例如,

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();
        }
    }
}

Then you could have a field of the class, something like: 然后,您可以拥有一个类的字段,例如:

// field of the class
private RunnablePlayer runnablePlayer;

and use this in your talk method: 并在您的交谈方法中使用它:

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();
}

Code not compiled or tested, but is presented to just give a general idea. 代码未经编译或测试,只是为了给出总体思路而提出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM