[reposted from the 11/17/05 Sleepycat blog entry]
I was recently tuning a benchmark that has lots of threads doing retrievals against JE. The code used a single Database handle shared across all threads. This turned out to present a minor bottleneck because the Database handle maintains a set of Cursors open against it. This set is used to check if all Cursors are closed against the Database when close() is called, but to do that we have to synchronize against it before updating it. So if a bunch of threads are sharing the same Database handle it makes for a synchronization bottleneck.
The moral of the story is that in a multi-threaded case, unless there's a good reason to share a Database handle, it's probably better to use separate handles for each thread.