You can use the Active Object pattern.
So make the World implementation an active object, in effect running all operations on its own thread.
A sample of the Active Object pattern with Boost Asio is here: boost::asio and Active Object
Whether it is (performance-wise) appropriate for you to make World an active object, I cannot tell. I have a feeling you should /simply/ not access World from many threads, instead only running computation-intensive stuff in the background that you don't need locks to coordinate, or where the locking overhead isn't significant.
In my comment here I showed an alternative approach to dispatching jobs with a lock-free queue implementation.