// Individually
generateCasesInternal(cleaner, c -> c.clearRef());
generateCasesInternal(cleaner, c -> c.doClean());
generateCasesInternal(cleaner, c -> c.doClear());
// Pairs
generateCasesInternal(cleaner,
c -> c.doClear(), c -> c.doClean());
// Triplets
generateCasesInternal(cleaner,
c -> c.doClear(), c -> c.doClean(), c -> c.clearRef());
generateExceptionCasesInternal(cleaner);
CleanableCase s = setupPhantom(COMMON, cleaner);
cleaner = null;
checkCleaned(s.getSemaphore(), true, "Cleaner was cleaned");
}
/** *Generateallpermutationsofthesequenceofrunnables *andtesteachone. *ThepermutationsaregeneratedusingHeap,B.R.(1963)PermutationsbyInterchanges. *@paramgeneratorthesupplierofaCleanableCase *@paramnthefirstindextointerchange *@paramrunnablesthesequenceofactions
*/
@SuppressWarnings("unchecked") void generateCases(Supplier<CleanableCase> generator, int n,
Consumer<CleanableCase> ... runnables) { if (n == 1) {
CleanableCase test = generator.get(); try {
verifyGetRef(test);
// Apply the sequence of actions on the Ref for (Consumer<CleanableCase> c : runnables) {
c.accept(test);
}
verify(test);
} catch (Exception e) { Assert.fail(test.toString(), e);
}
} else { for (int i = 0; i < n - 1; i += 1) {
generateCases(generator, n - 1, runnables);
Consumer<CleanableCase> t = runnables[n - 1]; int ndx = ((n & 1) == 0) ? i : 0;
runnables[n - 1] = runnables[ndx];
runnables[ndx] = t;
}
generateCases(generator, n - 1, runnables);
}
}
/** *Verifythetestcase. *AnyactionsdirectlyontheReferenceorCleanablehavebeenexecuted. *TheCleanableCaseundertestisgivenachancetodothecleanup *byforcingaGC. *Theresultiscomparedwiththeexpectedresultcomputed *fromthesequenceofoperationsontheCleanable. *TheCleanableitselfshouldhavebeencleanedup. * *@paramtestACleanableCasecontainingthereferences
*/ void verify(CleanableCase test) {
System.out.println(test); int r = test.expectedResult();
CleanableCase cc = setupPhantom(COMMON, test.getCleanable());
test.clearCleanable(); // release this hard reference
checkCleaned(test.getSemaphore(),
r == CleanableCase.EV_CLEAN, "Cleanable was cleaned");
checkCleaned(cc.getSemaphore(), true, "The reference to the Cleanable was freed");
}
/** *Verifythatthereference.getworks(ornot)asexpected. *IthandlesthecaseswhereUnsupportedOperationExceptionisexpected. * *@paramtesttheCleanableCase
*/ void verifyGetRef(CleanableCase test) {
Reference<?> r = (Reference) test.getCleanable(); try {
Object o = r.get();
Reference<?> expectedRef = test.getRef(); Assert.assertEquals(expectedRef.get(), o, "Object reference incorrect"); if (r.getClass().getName().endsWith("CleanableRef")) { Assert.fail("should not be able to get referent");
}
} catch (UnsupportedOperationException uoe) { if (r.getClass().getName().endsWith("CleanableRef")) { // Expected exception
} else { Assert.fail("Unexpected exception from subclassed cleanable: " +
uoe.getMessage() + ", class: " + r.getClass());
}
}
}
/** *TestthatreleasingthereferencetotheCleanerserviceallowsittobe *befreed.
*/
@Test(dataProvider = "cleanerSuppliers") publicvoid testCleanerTermination(Supplier<Cleaner> supplier) {
ReferenceQueue<Object> queue = new ReferenceQueue<>();
Cleaner service = supplier.get();
PhantomReference<Object> ref = new PhantomReference<>(service, queue);
System.gc(); // Clear the Reference to the cleaning service and force a gc.
service = null;
System.gc(); try {
Reference<?> r = queue.remove(1000L); Assert.assertNotNull(r, "queue.remove timeout,"); Assert.assertEquals(r, ref, "Wrong Reference dequeued");
} catch (InterruptedException ie) {
System.out.printf("queue.remove Interrupted%n");
}
}
try { if (semaphore.tryAcquire(Utils.adjustTimeout(200L), TimeUnit.MILLISECONDS)) {
System.out.printf(" Cleanable cleaned in cycle: %d%n", cycle); if (!expectCleaned) Assert.fail("Should not have been run: " + msg); return;
}
} catch (InterruptedException ie) { // retry in outer loop
}
} // Object has not been cleaned if (expectCleaned) Assert.fail("Should have been run: " + msg);
}
public Cleaner.Cleanable getCleanable() { return cleanup;
}
publicvoid doClean() { try {
addEvent(EV_CLEAN);
cleanup.clean();
} catch (RuntimeException ex) { if (!throwsEx) { // unless it is known this case throws an exception, rethrow throw ex;
}
}
}
Object obj = new String("a new string");
Cleaner.Cleanable c = cleaner.register(obj, () -> s1.release());
Reference r = (Reference) c; try {
Object o = r.get();
System.out.printf("r: %s%n", Objects.toString(o)); Assert.fail("should not be able to get the referent from Cleanable");
} catch (UnsupportedOperationException uoe) { // expected
}
try {
r.clear(); Assert.fail("should not be able to clear the referent from Cleanable");
} catch (UnsupportedOperationException uoe) { // expected
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.