While Async Chunk generation was a great attempt, there is a massive flaw in the logic.
The last stage on where the Pending/Prototype Chunk is converted to a real Chunk is being done asynchronously.
This operation modifies the world, by adding entities and tile entities to the world.
As it should be well known, modifying the world async is not safe.
It appears attempts was made to make this safer by using synchronization all over the place, but the attempt was not done correctly, and there is still huge risk that the world is going to be modified in unsafe ways.
Additionally, that synchronization has totally destroyed the server performance, creating blocking conditions on the main thread.
To resolve this, the final stage of chunk generation needs to be sent back to the main thread.
However care needs to be made to avoid a deadlock where the current generate method does a future.get().
I would suggest breaking it up into a 2 part process, so it does .get() on the Pending Chunk which doesn't need to return to main, and then add chunk to the world once it returns.
This also then removes the need for many synchronization blocks, further improving server stability and performance.
In an ideal world, the chunk map will only ever be touched synchronously.