Во-первых, я разрабатываю свою собственную реализацию DBCP (пул соединений с базой данных), как таковой,
Я не приму никаких предложений по использованию стороннего DBCP, такого как c3p0.
Я использую модель проектирования «производитель-потребитель» в качестве основного шаблона для своего DBCP.
PRODUCER | CONSUMER
Pn, ... P3, P2, P1 >> << C1, C2, C3, ... Cn
Как для производителя, так и для потребителя я использую очередь LinkedList.
ПРОДЮСЕР Очередь
Он будет заполнен максимальным числом экземпляров SQLConnectionWrapper. Я предпринял шаги, чтобы убедиться, что соединения в очереди уникальны. После .close() соединение будет,
- сначала удалить первый элемент в C-очереди, если он есть,
- в противном случае поставьте очередь в P-Queue.
Я использую служебный поток для удаления устаревших/истекших соединений в очереди и для создания новых соединений, чтобы сохранить минимальное количество соединений, как настроено.
ПОТРЕБИТЕЛЬ Очередь
Он будет заполнен экземплярами FutureTask. Приложения, использующие мой DBCP, будут вызывать
Connection conn = dbcp.getConnection(long timeout);
которые бы,
- сначала создайте Consumer FutureTask,
- удалить первый элемент в P-очереди, если он есть,
- иначе, очередь в C-очередь,
- блокировка .get(timeout) до тех пор, пока он не будет «накормлен» производителем или тайм-аутом, что наступит раньше.
Мой вопрос
Можно ли еще улучшить эту конструкцию? Какие-то заметные недостатки?
Мой приоритет — стабильность в среде параллельного использования. Из моего текущего тестирования я узнал, что требуется синхронизация с обеих сторон, поскольку задействованы 2 очереди.
Сейчас я изучаю такие идеи, как:
- уменьшить 2 очереди в 1 очередь (хотя мне трудно думать о том, как заставить P-сторону уничтожить C-сторону)
- создайте синхронизированный поток аннигилятора, избавив PRODUCER и CONSUMER от необходимости проверять друг друга.