Java, как остановить одновременную работу потоков - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь сделать остановку потока текста в речь всякий раз, когда метод talk (String text, boolean voiceEnabled) вызывается из ActionEvent с помощью кнопок.

При нажатии этих кнопок в текст передаются различные текстовые строки, которые запускают аудио в новом потоке.Если текущий поток все еще работает, но происходит новое событие 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 голосов
/ 26 апреля 2018

Похоже, вы хороните ключевые ссылки внутри анонимных внутренних классов, и я не понимаю, как вы можете получить к ним доступ, когда и при необходимости.Зачем это делать?Почему бы не создать экземпляр неанонимного класса, класса с полем AdvancedPlayer, класса, ссылка на который хранится в некоторой коллекции, например, List<...> или HashMap, или переменной, если выполняется только один или два, где выможет извлечь объект, получить его поле AdvancedPlayer и вызвать на нем .stop()?

например,

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

Код не скомпилирован или не протестирован, но представлен только для того, чтобы дать общее представление.

...