因此,我决定开始在Java8中使用CompletableFuture
,但我无法弄清楚此代码段出了什么问题:
public static void main(String...strings) throws Exception {
final Supplier<User> makeUserSupplier = () -> makeUser();
final Supplier<String> uuidSupplier = () -> makeUUID();
final CompletableFuture<User> futureUser = CompletableFuture.supplyAsync(makeUserSupplier);
final CompletableFuture<String> futureUUID = CompletableFuture.supplyAsync(uuidSupplier);
CompletableFuture.allOf(futureUser, futureUUID)
.thenApplyAsync(aVoid -> {
final User user = futureUser.join();
final String uuid = futureUUID.join();
return "received user + " + user + " and uuid is " + uuid ;
})
.handle((ok, e) -> {
System.out.println("ok----" + ok);
System.out.println("e----" + e);
return null;
});
}
private static User makeUser() throws RuntimeException {
// throw new RuntimeException("lkj");
return new User(1L, "mm", "ll", "kk");
}
private static String makeUUID() throws RuntimeException {
return UUID.randomUUID().toString();
// return "dummy";
}
其中User
类定义为:
@Data
@AllArgsConstructor
public class User {
private Long id;
private String username;
private String password;
private String role;
}
我得到的行为是:
UUID.randomUUID().toString()
时,控制台上什么都不会打印,当我使用某些随机String
时会得到结果。final String uuid = futureUUID.join();
时的那一行,然后程序停止,没有结果。有人可以尝试向我解释为什么在使用UUID时出现这种奇怪的行为吗?
PS:我刚刚开始学习CompletableFuture
,并想到了并行期货,然后偶然地来到了这里。
最诚挚的问候。
答案 0 :(得分:5)
这与UUID无关,除了它的生成需要一些时间并且您无需等待完成。
由于所有操作都在后台线程中进行,并且您从using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Patrol0 : MonoBehaviour
{
public float speed;
public Transform moveSpots;
private float waitTime;
public float StartwaitTime;
public float MinX;
public float MaxX;
public float MinY;
public float MaxY;
void start()
{
moveSpots = GetComponentInParent<Transform>();
waitTime = StartwaitTime;
moveSpots.position = new Vector2(Random.Range(MinX, MaxX), Random.Range(MinY, MaxX));
}
private void Update()
{
transform.position = Vector2.MoveTowards(transform.position, moveSpots.position, speed * Time.deltaTime);
if (Vector2.Distance(transform.position, moveSpots.position) < 0.2f)
{
if (waitTime <= 0)
{
moveSpots.position = new Vector2(Random.Range(MinX, MaxX), Random.Range(MinY, MaxX));
waitTime = StartwaitTime;
}
else
{
waitTime -= Time.deltaTime;
}
}
}
}
方法返回,因此JVM将确定不再有非守护进程线程正在运行并终止。
只需添加一个等待完成操作:
main
请注意,在原始代码中,您使用的是final Supplier<User> makeUserSupplier = () -> makeUser();
final Supplier<String> uuidSupplier = () -> makeUUID();
final CompletableFuture<User> futureUser = CompletableFuture.supplyAsync(makeUserSupplier);
final CompletableFuture<String> futureUUID = CompletableFuture.supplyAsync(uuidSupplier);
CompletableFuture.allOf(futureUser, futureUUID)
.thenApplyAsync(aVoid -> {
final User user = futureUser.join();
final String uuid = futureUUID.join();
return "received user + " + user + " and uuid is " + uuid ;
})
.handle((ok, e) -> {
System.out.println("ok----" + ok);
System.out.println("e----" + e);
return null;
})
.join(); // wait for completion
而不是.allOf(futureUser, futureUser)
,因此在.allOf(futureUser, futureUUID)
尚未完成时可能会执行链接操作,这可能会导致工作线程在futureUUID
通话中被封锁。
如果使用的话,您的代码会简单得多
futureUUID.join()
这也不受final CompletableFuture<User> futureUser = CompletableFuture.supplyAsync(() -> makeUser());
final CompletableFuture<String> futureUUID = CompletableFuture.supplyAsync(() -> makeUUID());
futureUser.thenCombineAsync(futureUUID, (user, uuid) -> {
return "received user + " + user + " and uuid is " + uuid;
})
.handle((ok, e) -> {
System.out.println("ok----" + ok);
System.out.println("e----" + e);
return null;
})
.join(); // wait for completion
的错误的影响,因为在工作线程中不需要allOf
调用。