Ditch your custom synchronized queue and use a BlockingCollection< T >.
With BlockingCollection
, you don't have separate threads controlling the queue. Rather, you have a queue, and threads can directly enqueue or dequeue items. The data structure itself handles any concurrency issues, and does non-busy waits when trying to dequeue.
See https://stackoverflow.com/a/19848796/56778 and https://stackoverflow.com/a/19823345/56778 for examples, or just search around a bit. Also, see my Simple Multithreading blog post for a little bit more detail.