可运行并发

Runnable concurrency

我正在玩弄 JMonkeyEngine。 在执行此操作时,我播放 JavaFX MediaPlayer。 这个 MediaPlayer 需要一个 Runnable 来处理当媒体完成时要做什么:

mp.setOnEndOfMedia(new Runnable() {
 @Override public void run() {
}}

我想做某事。像这样:

mp.setOnEndOfMedia(new Runnable() {
    @Override public void run() {
     //   instance.toggleLists();
        initMediaPlayer(mediaView, actualList.getPath()+actualList.getMediaLocation());
        detachChild(node);
        node = new TextureNode("mediaManagerTextureNode");
        node.init(app, mp);
        attachChild(node);
    }
});

这工作了几次,但最后我 运行 遇到了一些 运行 时间错误。

java.lang.IllegalStateException: Scene graph is not properly updated for rendering.
State was changed after rootNode.updateGeometricState() call. 
Make sure you do not modify the scene from another thread!
Problem spatial name: Root Node

是的,没错。我从外面弄乱了那个线程。 因为我有点不习惯这些东西...... 我不需要在 运行 方法中的那个位置做那件事,这就是必须做的事情,当这是 运行ning.

传递工作的最佳方式是什么,以便我的普通更新调用可以完成这些家务? 我已经尝试建立一个标志,将其设置为 true,当 true 时,通过应用程序本身的标准更新调用更新它,但不知何故我曾经 运行 进入此错误。那对我帮助不大。

MediaPlayer 只需要告诉我的 App "Hey! I'm ready! Give me a break and change me to something new!" 也就是说,运行 方法中发生了什么。

您可以在下次更新时使用 Application.enqueue 在主线程上创建一个 Runnable 运行 - 像这样:(假设 app 是对应用程序的引用)

mp.setOnEndOfMedia(new Runnable() {
    @Override public void run() {
       app.enqueue(new Runnable() {
            @Override public void run() {
                initMediaPlayer(mediaView, actualList.getPath()+actualList.getMediaLocation());
                detachChild(node);
                node = new TextureNode("mediaManagerTextureNode");
                node.init(app, mp);
                attachChild(node);
            }
       });
    }
});

如果您使用的是 Java 8,您可以使用 lambda 表达式对其进行缩写:

mp.setOnEndOfMedia(() -> {app.enqueue(() -> {
     initMediaPlayer(mediaView, actualList.getPath()+actualList.getMediaLocation());
     detachChild(node);
     node = new TextureNode("mediaManagerTextureNode");
     node.init(app, mp);
     attachChild(node);
}});