resultCount = verifyQueryResult(iter, 1);
assertEquals("Wrong number of query results", 2, resultCount);
}
public void testMultiThreadedAccess() {
final CountDownLatch latch = new CountDownLatch(1);
Runnable runnable = new Runnable() {
SailConnection sharedCon = con;
public void run() {
assertTrue(sharedCon != null);
try {
latch.countDown();
latch.await();
sharedCon.addStatement(painter, RDF.TYPE, RDFS.CLASS);
// wait a bit to allow other thread to add stuff as well.
Thread.sleep(500L);
Cursor<? extends Statement> result = sharedCon.getStatements(null, null, null, true);
int numberOfStatements = 0;
Statement st;
while ((st = result.next()) != null) {
numberOfStatements++;
assertTrue(st.getSubject().equals(painter) || st.getSubject().equals(picasso));
assertTrue(st.getPredicate().equals(RDF.TYPE));
assertTrue(st.getObject().equals(RDFS.CLASS) || st.getObject().equals(painter));
}
assertTrue("we should have retrieved statements from both threads", numberOfStatements == 2);
}
catch (StoreException e) {
e.printStackTrace();
fail(e.getMessage());
}
catch (InterruptedException e) {
fail(e.getMessage());
}
// let this thread sleep so the other thread can invoke close()
// first.
try {
Thread.sleep(1000L);
// the connection should now be closed (by the other thread),
// invoking any further operation should cause a
// IllegalStateException
sharedCon.getStatements(null, null, null, true);
fail("expected a ConnectionClosedException");
}
catch (ConnectionClosedException e) {
// do nothing, this is the expected behaviour
}
catch (Exception e) {
e.printStackTrace();
fail("expected a ConnectionClosedException");
}
}
}; // end anonymous class declaration
// execute the other thread
Thread newThread = new Thread(runnable, "B (parallel)");
newThread.start();
try {
latch.countDown();
latch.await();
con.addStatement(picasso, RDF.TYPE, painter);
// let this thread sleep to enable other thread to finish its business.
Thread.sleep(1000L);
con.close();
}