As of today, LWJGL CVS supports multiple threads, each rendering to a separate context.
This was one of the major gripes with LWJGL from the JOGL camp, and Ken Russel even stated that it would require a major rewrite of the LWJGL architecture to fix. It turned out he was absolutely right :). What I have done is to scrap the manually created java and native OpenGL/OpenAL binding source and replace it with generated ones. I wanted to retain the extensive checking and function signatures that we already had, so I could not generate from a gl/al C header file, like JOGL. Instead I chose to generate from template files, which are really annotated java interface files. Annotations are a java 1.5 feature, and they describe the meta-information needed for each OpenGL/OpenAL function that enables the generator to spit out proper checking, auto-compute lengths and types and all those LWJGL rules and conventions that have cropped up over the years.
The template files are still manually created from the spec and header file, but unlike the old way where each and every function has to be written in java and the native stubs created, a template file are much more terse and declarative. For example, there is always one method in the template for each opengl function, while in the old days there could be several, one for each nio buffer type and one additional one if the function supported VBO/PBO operation. Those functions are now auto-generated. More information about the generator can be found in the LWJGL CVS in doc/generator.txt.
So, finally, what does this mean to the average LWJGL user? Not much. The real advantage will come when multiple AWTGLCanvases is complete and used extensively. However there are a few things you should be aware of:
[*] The context, the function pointers and the extension flags are now per thread. OpenGL methods are still called statically like you’re used to, but the extension flags had to be put in an object. So if you’re using extensions (or GL > 1.1) and have code like this:
if (GLContext.GL_vertex_buffer_object) {
...
}
you have to replace it with this:
if (GLContext.getCapabilities().GL_vertex_buffer_object) {
...
}
That’s it.
[*] Calling OpenGL from a thread where a context is not current now correctly fails with an exception. Before, this was allowed and could lead to crashes and unexpected results.
[*] I have manually converted the entire OpenGL/OpenAL API to the new template format, so while I’ve been making sure that the generator generates code equivalent with the old manually created API, it’s likely that some bugs have cropped up either in the generator itself or in the template files. Please test 0.96 when it is released and report any inconsistencies so we can fix it as fast as possible. If you’re not the adventurous kind, please stay with 0.95 while I fight it out 
- elias