在播放JMF视频时更新视频控件UI时出现Java并发问题

在播放JMF视频时更新视频控件UI时出现Java并发问题,java,concurrency,jmf,Java,Concurrency,Jmf,我正在围绕JMF用纯Java构建一个视频播放器,带有完全定制的UI控件。一切都很顺利,直到我放入一个JLabel,以hh:mm:ss.ss格式更新当前播放时间。标签可接受更新,但偶尔一次暂停10秒以上,这是不可接受的 JMFPlayer是在SwingUtilities.invokeLater(new Runnable()…块中创建的。以下是UI更新代码: protected void createUIUpdater() { System.out.println("Creating UI

我正在围绕JMF用纯Java构建一个视频播放器,带有完全定制的UI控件。一切都很顺利,直到我放入一个JLabel,以hh:mm:ss.ss格式更新当前播放时间。标签可接受更新,但偶尔一次暂停10秒以上,这是不可接受的

JMF
Player
是在
SwingUtilities.invokeLater(new Runnable()…
块中创建的。以下是UI更新代码:

protected void createUIUpdater() {
    System.out.println("Creating UI updating worker thread");
    new Thread() {
        @Override
        public void run() {
            while(mediaPlayer.getState() == Controller.Started) {
                updatePlayPosition();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    System.err.println("Sleep interrupted!");
                }
            }
            System.out.println("UI Updater thread finished.");
        }
    }.start();
}

protected void updatePlayPosition() {
    Movie movie = timelineEditor.getMovie();
    movie.setInsertionPoint(Rational.valueOf(mediaPlayer.getMediaTime().getSeconds()));
    updateTimeLabel();
}

protected void updateTimeLabel() {
    Movie movie = timelineEditor.getMovie();
    Rational time = movie == null ? new Rational(0,1) : movie.getInsertionPoint();
    // ... hours/minutes/seconds calculated
    timeLabel.setText((hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes)
            + ":" + (seconds < 10 ? "0" + seconds : seconds)
            + "." + (frame < 10 ? "0" + frame : frame));
}
受保护的void createUIUpdater(){
System.out.println(“创建UI更新工作线程”);
新线程(){
@凌驾
公开募捐{
while(mediaPlayer.getState()==Controller.Started){
updatePlayPosition();
试一试{
睡眠(100);
}捕捉(中断异常e){
System.err.println(“睡眠中断!”);
}
}
System.out.println(“UI更新程序线程完成”);
}
}.start();
}
受保护的void updatePlayPosition(){
Movie Movie=timelineEditor.getMovie();
movie.setInsertionPoint(Rational.valueOf(mediaPlayer.getMediaTime().getSeconds());
updateTimeLabel();
}
受保护的void updateTimeLabel(){
Movie Movie=timelineEditor.getMovie();
Rational time=movie==null?新的Rational(0,1):movie.getInsertionPoint();
//…计算小时/分钟/秒
timeLabel.setText((小时<10?“0”+小时:小时)+“:”+(分钟<10?“0”+分钟:分钟)
+“:”+(秒数<10?“0”+秒数:秒)
+“+(帧<10?”0“+帧:帧));
}
StartEvent
上的
ControllerListener
中调用。在此期间,音频/视频正在播放


无可否认,我对Java中的并发性有点不熟悉,我相信有更好的方法来处理这个单独的线程。有什么建议吗?

您可以用ScheduledExecutorService替换您的线程/睡眠:


因为在使用sleep时,无法保证线程实际睡眠的时间,可能需要比您指定的时间更长的时间才能返回到运行状态。

仔细检查后,我的线程似乎执行得很好,只是在
mediaPlayer.getMediaTime()上偶尔会被阻塞。
(其中,
mediaPlayer
是一个
javax.media.Player


事实证明,调用
mediaPlayer.getMediaNanoseconds()
不会阻塞。

尝试调用标签invalidate,然后在每次更新后进行验证。问题不是JLabel没有重新绘制,而是线程似乎“挂起”。我在
updateTimeLabel()中输入了sysout语句
当问题发生时,不会调用sysout。尝试此操作后,似乎出现了相同的问题。执行线程有时会被阻塞。