Совместное использование переменной ThreadLocal в Java - PullRequest
2 голосов
/ 27 апреля 2011

В моем небольшом приложении у меня есть потоки двух классов - в основном писатели и читатели. Несколько читателей могут быть назначены одному писателю. Автор взаимодействует со своими читателями, записывая их переменную chunkBuffer.

Теперь я не могу полностью обдумать проблему безопасности потока: если я не сохраню chunkBuffer в статической переменной ThreadLocal, все читатели будут использовать один chunkBuffer, что плохо. Но если я сохраню chunkBuffer в статическом ThreadLocal, средство записи, будучи отдельным потоком, получит свою собственную копию chunkBuffer и продолжит запись в нее, пока ни одна из записанных ею данных не достигнет читателей. Можете ли вы объяснить мне, в чем здесь проблема? Большое спасибо.

Редактировать Другими словами, есть ли способ создать поле, которое будет уникальным для каждого отдельного экземпляра подкласса потока (например, ThreadLocal), но может быть доступно из других потоков по требованию?

Ответы [ 2 ]

2 голосов
/ 27 апреля 2011

Нет.

ThreadLocal для личных данных потока. В вашем случае вам нужны объекты для связи , поэтому вам нужны объекты другого типа.

Я думаю, что лучше всего использовать синхронизированные очереди: java.util.concurrent.LinkedBlockingQueue<E>.

Очереди позволяют производителю вставлять данные и потребителю потреблять. Если он синхронизирован, это позволяет делать это из разных потоков, не нарушая структуру.

Вы можете разделить очередь между соответствующими авторами / читателями:

Writer 1 -> queue 1 -> [readers A/B/C]

Writer 2 -> queue 2 -> [readers D/E/F]

У каждого писателя и читателя будет свой поток. Каждый читатель будет пытаться взять один элемент из своей очереди, если нет элементов. Если вам нужно более мудро управлять своими читателями, вы можете попробовать более сложный подход, но я думаю, что это хорошая отправная точка.

0 голосов
/ 27 апреля 2011

Не думаю, что вы хотите использовать переменную ThreadLocal.Вам действительно нужен механизм уведомления.

Writer выполняет следующие действия:

  1. Пишет читателю chunkBuffer
  2. Уведомляет читателя о новых данных.

Есть много способов сделать это в java-параллелизме, но обычно проще и безопаснее использовать ArrayBlockingQueue.В вашем случае использования это звучит так, как будто каждый Reader будет иметь свой собственный ArrayBlockingQueue, и ему просто нужно считать из очереди.

Это, конечно, будет зависеть от вашего варианта использования.Нужно ли всегда работать с самыми последними данными, или вам нужно работать над каждой записью в chunkBuffer?Подобные вопросы необходимы для выяснения, какой механизм вам нужен.

Примечание. Перейдите к @helios для упоминания синхронных очередей, надеюсь, мой ответ добавляет ценность.

...