The device can be used by any thread. Feel free to load textures/models etc on any or all threads.
Contexts can only be used by one thread (at a time), but you can create as many (deferred) contexts as you need.
When you've finished submitting draw calls to a deferred context, you can call FinishCommandList to turn it into a ID3D11CommandList. You can then hand this over to your "main" thread (the one that owns the immediate context), and it can call ExecuteCommandList to send those commands to the GPU.
Main thread owns "immediate context" and submits command lists.
Worker threads own "deferred contexts" and create command lists.
Every thread can use the device.
From what I know, you use threads to do work in parallel to load as many resources as possible at a time. But In std::threads, to make it work properly, I've to use thread.join() with mainthread for the mainthread to wait for that thread to finish the execution. Doesn't this completely destroy the purpose of threads? This is just like calling functions then.