【发布时间】:2015-03-08 07:30:47
【问题描述】:
我正在练习 Cay S. Horstmann 所著的“真正不耐烦的 Java SE 8”一书。
写一个方法
public static <T> CompletableFuture<T> repeat( Supplier<T> action, Predicate<T> until)异步重复操作,直到它产生一个值 被
until函数接受,它也应该运行 异步。使用读取 a 的函数进行测试java.net.PasswordAuthentication来自控制台,还有一个函数 通过睡眠一秒钟然后模拟有效性检查 检查密码是否“秘密”。
我想出了以下代码,但随机密码生成策略似乎让我失望了。所有线程不断选择相同的密码,这看起来很奇怪。
public static <T> CompletableFuture<T> repeat(final Supplier<T> action, final Predicate<T> until) {
final CompletableFuture<T> futureAction = supplyAsync(action);
final boolean isMatchFound = futureAction.thenApplyAsync(until::test).join();
final T suppliedValue = getSuppliedValue(futureAction);
if (isMatchFound) {
LOGGER.info("Got a match for value {}.", suppliedValue);
return futureAction;
}
return repeat(() -> suppliedValue, until);
}
private static <T> T getSuppliedValue(final CompletableFuture<T> futureAction) {
try {
return futureAction.get();
} catch (InterruptedException | ExecutionException e) {
LOGGER.error(e.getMessage());
}
return null;
}
测试用例:
@Test
public void testRepeat() {
Supplier<PasswordAuthentication> action = () -> {
final String[] passwordVault = new String[] { "password", "secret",
"secretPassword" };
final int len = passwordVault.length;
return new PasswordAuthentication("mickeyMouse",
passwordVault[ThreadLocalRandom.current().nextInt(len)].toCharArray());
};
@SuppressWarnings("static-access")
Predicate<PasswordAuthentication> until = passwordAuth -> {
try {
currentThread().sleep(1000);
} catch (InterruptedException e) {
fail(e.getMessage());
}
final String password = String.valueOf(passwordAuth.getPassword());
LOGGER.info("Received password: {}.", password);
return password.equals("secret");
};
repeat(action, until);
}
运行一次,看看选择相同的密码有多奇怪:
2015-01-09 15:41:33.350 [线程 1] [信息] n.a.j.j.c.PracticeQuestionsCh6Test - 收到密码: 秘密密码。 2015-01-09 15:41:34.371 [线程 3] [信息] n.a.j.j.c.PracticeQuestionsCh6Test - 收到密码: 秘密密码。 2015-01-09 15:41:35.442 [线程 5] [信息] n.a.j.j.c.PracticeQuestionsCh6Test - 收到密码: 秘密密码。 2015-01-09 15:41:36.443 [线程 7] [信息] n.a.j.j.c.PracticeQuestionsCh6Test - 收到密码: 秘密密码。 2015-01-09 15:41:37.451 [线程 9] [信息] n.a.j.j.c.PracticeQuestionsCh6Test - 收到密码: 密码。
【问题讨论】:
标签: multithreading concurrency java-8 thread-local completable-future