The way I've got it rigged is you can have a separate resource loading thread that loads stuff from disk into ByteBuffers. But then what it does is queue GL code up in the main thread so that I don't need to do any fiddly thread context switching. It's still fiddly and I've not really used it in anger. Er, or at all, even. The main problem being it's usually quite difficult to know what you need to load next until the time comes when you actually need to display it. Especially as some things need to be loaded with dependencies - consider loading a GL model for example, it'll have to bring in a bunch of textures asynchronously as well, etc, etc.
I find it generally just easier to load everything on demand and as much as feasible up front during the splash screen