Cara, temmuitas hipóteses, mas de cara eu te falo que isso é banco de dados.
Vamos lá!
Existe consultas/manipulação em loops? Se existir, como está sendo feita os comits em banco?
Normalmente, quando a gente começa a desenvolver, temos a tendencia de colocar o commit dentro do loop. E isso é um desastre.
Bom, primeiro vc usa o preperedStatement ao invéns do Statement. Daí, dentro do loop vc envoca o método executeUpdate e ao sair do loop o commit. Assim, ele atualiza o banco de uma vez soh, ao invez de fazr isso registro por registro.
Se for consulta, vc parametriza o PreperedStatement. Ele é otimizado e compila o seu sql. Se vc fizer a mesma consulta com sql puro, ela será mais lenta que utilizando o PreparedStatement.
Outra fonte de lerdeza é como vc trata as conexões ao banco. Vc costuma liberar as conexões assim que termina de usar? Se não, isso vai acumulando conexões no banco. Dependendo da forma que vc configurou o banco, hehehehe, o desenpenho da sua máquina cai a zero.
Por fim, dê uma olhada nas suas pesquisas. Pesquisas mal feitas e cruzamentos desnecessário forçam muito o banco e faz que o desempenho mingüe.
Olha, vc pode fazer consultas de duas formas, a bom e a ruim. O problema é que da forma ruim é mais fácil.
Como vc usa o synchronized? O synchronized deve ser utilizado só e somente só no bloco que trata com o banco. Qualquer outra parte do código deve estar fora do synchronized.
Sabe, por enquanto, esses foram os eros mais comuns que eu lembrei.