Это классическая проблема производитель-потребитель.
Есть много способов решить эту проблему, но проще всего иметь одну блокировку в очереди, а когда вы добавляете или удаляете элемент из нее, в производителе или потребителе, соответственно, блокируете очередь, выполняете работу , а затем разблокировать очередь. У потребителя обработайте товар, а у производителя перейдите к получению нового предмета.
Возможно, вы захотите разложить свои структуры данных, а затем определить блокировки, конкретно описав, что блокирует блокировка, поэтому вы уверены, что все ваши данные, к которым имеют доступ оба потока, остаются синхронизированными.
Спасибо, что отметили это как домашнюю работу; Я надеюсь, что это поможет вам начать в правильном направлении. Вы также можете захотеть заблокировать такие вещи, как печать на консоли, чтобы эти операции не перекрывались.