This will abort both the producer and consumer possibly removing items from the queue to make room for our END_OF_QUEUE marker.
Wait for both the producer and consumer threads (if any) to finish
Wait for the consumer thread (if any) to finish
Wait for the producer thread (if any) to finish
Note: It's not clear what the correct behavior of this method is.
Run the function in a separate producer thread.