强制方法在继续之前完成

时间:2017-07-11 03:08:27

标签: java concurrency thread-safety lwjgl

我正在研究一些敏感的LWJGL代码,需要确保在执行任何其他代码之前创建我的显示,因此需要GL上下文。

为了清楚地说明我目前的困境,请采取以下措施:

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

    GLShader shader = new StaticShader();
}

我的GL创建的开始发生在display.start(),其中创建一个单独的线程,并且在单独的线程中,我的人工显示被创建。

除了这是问题所在,我把它放在一个单独的线程中。所以然后我的程序继续并开始过早地执行调用更多GL代码的new StaticShader(),打破程序。 (在创建显示之前无法执行。)

我正在尝试做的是同时实现我已经拥有的两个线程,但确保start()方法在任何事情之前被称为完全别的是。

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

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

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

这是Threader

public static void createThread(Runnable behaviour, String name) {
    new Thread(behaviour, name + behaviour.hashCode()).start();
}

现在你可能会注意到start方法中的synchronized关键字,这只是一次我无法获得的尝试。我也尝试了以下(我实际上从另一个StackOverflow答案中获取):

@Override
public void run() {
    synchronized(this) {
        // GL code
    }
}

我已经检查了其他StackOverflow的答案,但要么不理解它们,要么在我的情况下不帮助我。使用main方法中给出的第一个代码块,就是我希望代码看到使用它的人。我正在尝试将线程创建放在GlDisplay中以隐藏它。
有什么想法吗?

修改

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

3 个答案:

答案 0 :(得分:1)

您可以使用java.util.concurrent.CountDownLatch来实现它,这有助于使线程等待其他线程上的操作完成。请参阅有关使用它的内容和方法的参考资料。

示例

public static void main(String[] args) {

    CountDownLatch cdl = new CountDownLatch(1);

    // pass the CountDownLatch into display
    GLDisplay display = new GLDisplay(cdl);
    display.start();

    // wait for the latch to have been counted down in the disp thread
    try
    {
        cdl.await();
    }
    catch (InterruptedException e)
    {
        e.printStackTrace();
    }

    GLShader shader = new StaticShader();
}

在您的GLDisplay主题中,调用CountDownLatch的countDown方法

答案 1 :(得分:0)

我可能会误解某些内容,但请尝试以下方法:

public static void createThread(Runnable behaviour, String name) {
    Thread t = new Thread(behaviour, name + behaviour.hashCode()).start();
    t.join();
}

通过调用join(),程序应该等待线程完成。

答案 2 :(得分:0)

我现在还记得,无论如何我都无法对两个单独的线程使用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.
}

当在第二个线程中到达并且释放了线程锁时,第一个线程继续执行它的活动。就这么简单!