Как организвовать многопоточное взаимодействие с БД в Java?
Подход из мира JEE (и не только):
Для всего многопоточного приложения используется реализация "пула соединений", которая обслуживает соединения с СУБД (одной или несколькими).
Прикладной код каждого потока обращается к пулу, получает из него соединение с СУБД, выполняет определенную работу (запрос или запросы), закрывает транзакцию и закрывает соединение (в результате соединение возвращается в пул). 
В этом случае предполагается, что прикладной код удерживает соединение минимально необходимое время.
Такой подход позволяет обслуживать много потоков относительно малым числом соединений с СУБД и экономить время на установку соединения, т.к. в нормальных условиях в пуле присутствует процент свободных и готовых к работе соединений. 
Плюс прикладной код не содержит настроек для конкретной СУБД, все настройки хранятся на уровне файлов конфигурации пула соединений.
Логика управления пулом может самостоятельно устанавливать новые соединения (если все существующие заняты), завершать соединения (если очень много свободных), "отбирать" соединения у прикладного кода, если по соединению долго не было никакой активности (банально забыли закрыть соединение), проверять незанятые соединения на "живость", выполняя диагностические SQL-запросы и т.п.
Примеры реализации пулов соединений:Apache Commons DBCPc3p0:JDBC DataSources/Resource PoolsThe Tomcat JDBC Connection Pool
В мире Java для работы с БД принято использовать Hibernate. Но, как обычно, есть проблемы.