多个线程不能同时工作

时间:2014-05-17 05:08:50

标签: java multithreading swing

我有一个java程序,我正在使用TTS(文本到语音),在那里我想要一个动画gif出现在屏幕上。我正在使用Netbeans GUI构建器,所以我编写了一个新的jpanel form并在该表单的标签中添加了gif(java jpanel表单),之后我将这个java作为jpanel添加到我的主java文件(通过拖放)。但问题是,只要TTS开始说话就会停止gif的动画。如何让它一起工作? 注意:我使用freeTTS将文本转换为语音

代码:

private static final String VOICENAME = "kevin16";
VoiceManager voiceManager = VoiceManager.getInstance();
.....
........
Voice voice;
voice = voiceManager.getVoice(VOICENAME);
voice.allocate();
....//Some code here
t4.setText("" + ran);  
voice.speak(t4.getText()); 
listenanum.setText("" + d);
listenanum.setVisible(false);

1 个答案:

答案 0 :(得分:3)

我必须查找FreeTTS Javadoc,这证实了我的想法。

speak上的Voice方法会阻止语音文本完成。方法speak(String)调用speak(FreeTTSSpeakable speakable),它有这个Javadoc:

  

说出给定的队列项。这是一种不同步的同步方法   返回直到说话完全被说出或被取消。

然而,在Swing中,只要你在UI线程中做了一件事,它就无法做任何其他事情。因此,您的动画将停止,因为它还需要UI线程来重新绘制图像。

解决此问题的最佳方法可能是深入研究语音API并在processUtterance(Utterance u)上使用Voice方法。这个方法是异步的;当语音在不同的语音输出线程上完成时,它会立即返回。

然而,一个更简单的解决方案就是在另一个线程上调用speak方法。

final String textToSpeak = t4.getText();
Thread speechThread = new Thread(new Runnable() {
    public void run() {
        voice.speak(textToSpeak);
    }
});
speechThread.start();

实际上,使用线程池比每次启动新线程更好,但这超出了您的直接问题。您可以搜索StackOverflow或查看java.util.concurrent.ThreadPoolExecutor以获取更多信息。