Вы можете инициализировать одиночный SessionFactory. Это на самом деле рекомендуется.
Затем каждый поток должен создать сеанс с использованием фабрики сеансов и выполнить транзакцию (и).
На самом деле это очень распространенный шаблон, используемый в веб-приложениях. Шаблон Open Session in View, о котором упоминает @kvista, в основном представляет собой фильтр сервлета, который создает сеанс, начинает транзакцию, делегирует то, что продолжает обработку запроса, и в конце фиксирует или откатывает транзакцию. И поскольку каждый запрос обрабатывается отдельным потоком в контейнере сервлета, вы можете увидеть, насколько близки эти два случая.
В вашем случае было бы неразумно выполнять много транзакций в каждом потоке. На самом деле это основная идея выполнения пакетных процессов в многопоточной (в идеале JTA) среде. Однако следует отметить, что сеанс представляет собой постоянный контекст, который действует как кэш-память, и вам, вероятно, следует время от времени очищать его, чтобы избежать утечек памяти.