throws Exception {
final Object parent = new Object();
final Object child1 = new Object();
final Object child2 = new Object();
final TransactionRunner runner = new TransactionRunner(env);
runner.setMaxRetries(0);
/* Write a record in each db. */
runner.run(new TransactionWorker() {
public void doWork() throws Exception {
assertNull(map1.put(ONE, ONE));
assertNull(map2.put(ONE, ONE));
}
});
/*
* A thread to open iterator 1, then wait to be notified, then open
* iterator 2.
*/
final Thread thread1 = new Thread(new Runnable() {
public void run() {
try {
runner.run(new TransactionWorker() {
public void doWork() throws Exception {
synchronized (child1) {
ListIterator i1 =
(ListIterator) map1.values().iterator();
i1.next();
i1.set(ONE); /* Write lock. */
StoredIterator.close(i1);
synchronized (parent) { parent.notify(); }
child1.wait();
Iterator i2 = map2.values().iterator();
assertTrue(i2.hasNext());
StoredIterator.close(i2);
}
}
});
} catch (DeadlockException expected) {
} catch (Exception e) {
e.printStackTrace();
fail(e.toString());
}
}
});
/*
* A thread to open iterator 2, then wait to be notified, then open
* iterator 1.
*/
final Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
runner.run(new TransactionWorker() {
public void doWork() throws Exception {
synchronized (child2) {
ListIterator i2 =
(ListIterator) map2.values().iterator();
i2.next();