code: public static JCGLAsyncInterfaceGL33Type newAsync(
      final Supplier<JCGLContextType> c)
    {
      try {
        NullCheck.notNull(c, "Supplier");
  
        final ThreadFactory tf = r -> {
          final int id = ID_POOL.getAndIncrement();
          final Thread t = new Thread(r);
          t.setDaemon(false);
          t.setName("com.io7m.jcanephora.async.gl:" + id);
          return t;
        };
  
        final AtomicReference<JCGLContextType> context =
          new AtomicReference<>();
        final AtomicReference<JCGLInterfaceGL33Type> g33 =
          new AtomicReference<>();
  
        final ExecutorService exec = Executors.newFixedThreadPool(1, tf);
  
        exec.submit(() -> {
          final JCGLContextType cc = c.get();
          cc.contextMakeCurrent();
          context.set(cc);
          g33.set(cc.contextGetGL33());
        }).get();
  
        return new JCGLAsyncInterfaceGL33(context.get(), g33.get(), exec);
      } catch (final InterruptedException e) {
        throw new JCGLExceptionConcurrency(e);
      } catch (final ExecutionException e) {
        throw new JCGLException(e.getCause());
      }
    }
docs: Construct an async interface, evaluating the given function to obtain a
  context that will be used exclusively for async calls. A new dedicated
  thread will be created for GL calls, and the context returned from {@code
  c} will be made current on that thread.
  
  @param c The context supplier
  
  @return A new async interface