It sounds like your main thread is running the simulation and your auxiliary thread is rendering the entities. You can probably get away with reading the entity without locking if you make sure that you only read from it. You need to look at it from a memory contention standpoint. If you don't lock, you run the risk of having part of the data change on you while you are reading from it. It's up to you if that is a bad thing or not.
Double buffering the data may help prevent partial updates, but you need to prevent the buffers from being swapped while somebody is reading from it (again locking).
You might want to consider your threading approach. Having a separate render thread may not be the best thing in this case. You might want to have the main thread do an update pass then a render pass but use a worker thread pool to achieve parallelism. Instead of having a single "coarse grain" thread for rendering, use a bunch of work threads to get "fine grain" threading within a single phase.
For example: In your main game loop, you update your game objects by passing them all off to worker threads to be done in parallel. Then when they're all done, you go to the render phase. In your render phase, you do entity visibility culling and build render commands per entity in a bunch of worker threads in parallel. if you are able to encapsulate the render commands, you can build a list of them in the main thread and then pass the entire list off to a coarse grained rendering thread for execution while your main thread goes back to updating.