Это не прямой ответ на ваш вопрос, но может быть лучше переосмыслить вашу модель параллелизма. Блокировки - ужасный способ синхронизировать что угодно - слишком низкий уровень, подверженность ошибкам и т. Д. Попробуйте переосмыслить свою проблему с точки зрения параллелизма передачи сообщений :
Идея заключается в том, что каждый поток представляет собой свой собственный плотно замкнутый цикл сообщений, и каждый поток имеет «почтовый ящик» для отправки и получения сообщений - мы будем использовать термин MailboxThread, чтобы отличать эти типы объектов от простых Джейн темы.
Таким образом, вместо двух потоков, обращающихся к одному и тому же буферу, вместо этого у вас есть два MailboxThreads, отправляющие и получающие сообщения между собой (псевдокод):
let filter =
while true
let image = getNextMsg() // blocks until the next message is recieved
process image
let camera(filterMailbox) =
while true
let image = takePicture()
filterMailbox.SendMsg(image) // sends a message asyncronous
let filterMailbox = Mailbox.Start(filter)
let cameraMailbox = Mailbox.Start(camera(filterMailbox))
Теперь вы обрабатываете потоки, которые вообще не знают или не заботятся о каких-либо буферах. Они просто ждут сообщений и обрабатывают их, когда они доступны. Если вы отправляете много сообщений для обработки filterMailbox, эти сообщения ставятся в очередь для последующей обработки.
Сложная часть - это реализация вашего объекта MailboxThread. Несмотря на то, что для правильной реализации требуются некоторые творческие способности, вполне возможно реализовать эти типы объектов таким образом, чтобы они удерживали поток открытым при обработке сообщения и высвобождали исполняющий поток обратно в пул потоков, когда не осталось сообщений для обработки (эта реализация позволяет вам завершать работу приложения без висячих потоков).
Преимущество здесь в том, что потоки отправляют и получают сообщения, не беспокоясь о блокировке или синхронизации. За кулисами вам нужно заблокировать свою очередь сообщений между постановкой или снятием очереди сообщения, но эти детали реализации полностью прозрачны для вашего клиентского кода.