How to efficiently use Threads and locks - C#