Java 在继续之前强制方法完成

Java 在继续之前强制方法完成,java,concurrency,thread-safety,lwjgl,Java,Concurrency,Thread Safety,Lwjgl,我正在处理一些敏感的LWJGL代码,需要确保在执行任何其他代码之前创建我的显示,从而创建GL上下文 为了清楚地说明我目前的困境,请举以下例子: public static void main(String[] args) { GLDisplay display = new GLDisplay(); display.start(); GLShader shader = new StaticShader(); } public static void createThre

我正在处理一些敏感的LWJGL代码,需要确保在执行任何其他代码之前创建我的显示,从而创建GL上下文

为了清楚地说明我目前的困境,请举以下例子:

public static void main(String[] args) {
    GLDisplay display = new GLDisplay();
    display.start();

    GLShader shader = new StaticShader();
}
public static void createThread(Runnable behaviour, String name) {
    Thread t = new Thread(behaviour, name + behaviour.hashCode()).start();
    t.join();
}
我的总账创建开始于display.start,其中创建了一个单独的线程,并在单独的线程中创建了我的显示

除了这是问题所在,我有一个单独的线程。然后我的程序继续运行,开始过早地执行新的StaticShader,它调用了更多的GL代码,破坏了程序。在创建显示之前无法执行

我要做的是,同时实现两个线程,我已经有了,但要确保在调用任何其他线程之前,先完全调用start方法

以下是start方法的工作原理:

public synchronized void start() {
    Threader.createThread(this, "GLDisplay");
}

@Override  // public class GLDisplay extends Runnable
public void run() {
    // GL code goes here.
}
这是Threader:

现在您可能会注意到start方法中的synchronized关键字,这只是我的一次尝试,但没有成功。我还尝试了以下我从另一个StackOverflow答案中得到的答案:

@Override
public void run() {
    synchronized(this) {
        // GL code
    }
}
我检查了其他答案,但要么不理解,要么在我的情况下不帮助我。对于main方法中给出的第一个代码块,这就是我希望代码对使用它的人的外观。我试图将线程创建放在GlDisplay中以隐藏它。 有什么想法吗

编辑:

我不能简单地等待GLDisplay关闭Thread.join,因为存在一个while循环,可以更新整个程序的显示。
这就是我使用多线程的全部原因。允许这个永远结束的循环在我执行程序中的其他操作时运行。通过关闭线程,我关闭了循环,清理了显示,并从内存中释放了GL上下文,再次使着色器代码由于缺少现有上下文而失败。

我可能误解了什么,但请尝试以下操作:

public static void main(String[] args) {
    GLDisplay display = new GLDisplay();
    display.start();

    GLShader shader = new StaticShader();
}
public static void createThread(Runnable behaviour, String name) {
    Thread t = new Thread(behaviour, name + behaviour.hashCode()).start();
    t.join();
}
通过调用join,程序应该等待线程完成。

您可以使用来实现它,这有助于使线程等待其他线程上的操作完成。请参阅关于什么和如何使用它的参考资料

例如:


在GLDisplay线程中,调用CountDownLatch的倒计时方法。我现在记得,无论如何,我不能对两个单独的线程使用GL代码,但这不是重点

实际上,我不需要使用任何线程锁类或任何东西,而是可以做如下简单的事情:

private Boolean threadLock = true;
public void start() {
    Threader.createThread(this, "GLDisplay");
    while (true) {
        synchronized(threadLock) {
            if (!threadLock) break;
        }
    }
}

@Runnable
public void run() {
    // Do GL code.
    synchronized(threadLock) { threadLock = false; }
    // Do the rest of whatever I'm doing.
}

当第二个线程到达线程锁并释放时,第一个线程继续执行其活动。就这么简单

如果需要按顺序运行,为什么要在单独的线程中运行?@QBrute我希望所有GL组件都存储在主线程中,然后在需要时输入显示线程。因此,通过创建一个显示,我创建了第二个线程,稍后可以在“运行”中添加组件。您可以将着色器实例传递到显示中吗?@MichaelMarkidis我以前就这样设置过,但根据我将要做的工作,它必须完全基于对象,我可以在任何地方初始化实例,而不是调用createShaderGLShader着色器方法等@MichaelMarkidis即使我传入了它,它也会在显示器完成自身创建之前传入。不!那个显示线程就是我的整个窗口!没有它,该计划将不复存在。我可能应该说,我有一个主循环,在整个程序周期中都在该线程中运行。请原谅。如果该线程关闭,那么GL上下文将再次丢失。哦,我明白了,我想我有点困惑,很抱歉我帮不了什么忙。因此,您实际需要的是在程序继续运行之前,显示线程中的线程器分离线程要完成吗?我希望分离线程仍然存在。线程将不会有任何完成。我试图让start方法完成,或者说是它的某一部分,然后每隔一个线程继续。在完成该部分后,start仍在处理它自己方法的其余部分,但其他线程也在继续。噢,JavaDoc的开头正好解释了我需要什么。让我读一下,我马上就来嗯,等等。这不需要我将着色器对象存储在辅助线程中吗?我需要像以前一样把它放在程序的主线程中,没有必要把着色器放在次线程中。只需将闩锁传递到次螺纹。。您可以在执行过程中的任何时候调用辅助线程锁存器上的contDown方法,以指示主线程开始恢复。那么您能给我举个例子吗?我在看JavaDoc和相关示例,它们似乎使用了多个与主线程无关的辅助线程
在布尔值上同步的最佳实践:2为什么不必要地使用忙等待循环和自旋?在这种情况下,我只想使用@OTM answers中的倒计时锁存器。@MichaelMarkidis当然,我想使用它们,除非我发现没有办法使用它们,而不必合并到main方法中。此方法只是隐藏它,因此可以在库中使用,而不需要用户自己实现它。我仍然在研究它,我不喜欢布尔方式,它太脏了。我想说的是,你仍然可以在这个类内部使用CountDownLatch。只需使用闩锁,而不是锁threadLock@MichaelMarkidis啊!!对不起我明白你现在的意思了!将实例放在类中。那会好得多。谢谢你。