我迁移到 spring boot 3 和 java 21。由于我要进行补丁休息调用,因此我需要依赖项 org.apache.httpcomponents.client5:httpclient5:5.2.2。
但有了这种依赖性,如果将 org.springframework.web.client.RestTemplate 与 RequestEntity.get 一起使用,我会得到“java.lang.IllegalArgumentException:无效代理”。
在相同的设置下,补丁调用工作得很好。
有谁知道为什么会发生这种情况?我没有代理。我必须定义默认代理吗?
不幸的是,对于此链接:https://github.com/apache/httpcomponents-client/tree/5.1.x/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientConfiguration.java 我得到 404。:-(
我尝试仅使用 apache 依赖项而不使用 Resttemplate 并得到相同的异常。
HttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(uri);
httpGet.setHeader(HttpHeaders.AUTHORIZATION, token);
httpGet.setHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
Run Code Online (Sandbox Code Playgroud) apache-httpclient-5.x spring-resttemplate java-21 spring-boot-3
JDK 开发人员建议永远不要池化虚拟线程,因为创建和销毁虚拟线程的成本非常低。我对池的想法有点困惑,因为池通常意味着两件事:
我知道 JDK 开发人员希望我们永远不要重用虚拟线程,而生命周期问题让我感到困惑,因为如果有多个虚拟线程的生命周期与应用程序本身一样长,那么听起来可能像是没有重用的池化。
那么,虚拟线程是否应该快速死亡,或者具有较短的有界生命周期,或者多个虚拟线程阻塞、偶尔被唤醒以处理某些任务并且具有非常长的生命周期是否可以?
还有其他人也注意到 Java 21 中 Java 泛型的变化吗?
我们使用Jdbi进行数据库访问,当更新到 Java 21 时,会出现问题,因为无法再确定泛型类型。
在调试时我注意到一个条件
java.lang.reflect.Type type = ...
if (type instanceof Class) {..}
Run Code Online (Sandbox Code Playgroud)
其中type是一个接口,在 Java 17 中计算结果为false,但true在 Java 21 中计算结果为 。
Jdbi的某些泛型依赖于Geantyref库。静态方法GenericTypeReflector.getTypeParameter(..)在 Java 17 中返回泛型类型,但null在 Java 21 中返回。
在发行说明或其他公告中,我找不到任何有关 Java 21 中有关泛型的更改的信息。也没有发现向后兼容的重大更改。
我假设一些内部结构可能由于记录反射 (JEP-440) 或开关的模式匹配 (JEP-441) 而发生了变化,但我已经将这些功能用作 17 预览版功能,没有任何问题。
有人知道是什么导致了这些变化以及为什么吗?
我想我已经明白了。我将问题追溯到记录类的构造函数参数。似乎在 Java 21 中,记录类的默认构造函数的参数不知何故不具有泛型类型。所以对于像这样的记录
record Person(Optional<String> name, Optional<Integer> age) {}
Run Code Online (Sandbox Code Playgroud)
泛型类型String并 …
我确实知道平台线程很昂贵,因为它需要更多内存并且容易发生 CPU 上下文切换。
但是,在虚拟线程的情况下,少数平台线程可以服务难以想象的大量虚拟线程,虚拟线程是否仍然需要内存空间来钝化上下文/堆栈,然后将其附加到载体线程?
它对记忆有何影响?
为什么自旋 10000 个虚拟线程不会因内存不足而消亡,而 10000 个平台线程则会因内存不足而消亡?
他们都需要相同的堆栈吗?以及需要维护应用程序相关信息的上下文,对吧?
内存中是否存在仅适用于平台线程的额外开销,这就是我们说虚拟线程在内存中“更轻”的原因?如果是的话,是什么造成了这种差异?
当Java 21引入有序集合时,我非常高兴开始使用它们。但后来我很快发现JDK的各个角落似乎都会自然地应用新的排序接口,但它们并没有应用。我找不到对此的任何确认,也找不到任何证据表明未来有计划进一步将排序集合接口的使用扩展到更多 JDK 中。这让我感到惊讶,因为 JDK 的作者通常倾向于保持事物的一致性和完整性。
一个具体的例子是EnumSet。据我所知,没有根本原因EnumSet不能/不应该实施SequencedSet. 难道只是没有人愿意付出努力来实现一种reversed()方法吗EnumSet?或者有什么更严重的问题阻止了它?
我正在尝试测试 Java 21 的外部函数和内存功能。这是我的代码:
\npublic static void main(String[] args) {\n // 1. Find foreign function on the C library path\n Linker linker = Linker.nativeLinker();\n SymbolLookup stdlib = linker.defaultLookup();\n MethodHandle radixsort = linker.downcallHandle(stdlib.find("radixsort").orElseThrow(), FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_CHAR));\n // 2. Allocate on-heap memory to store four strings\n String[] javaStrings = {"mouse", "cat", "dog", "car"};\n\n // 3. Use try-with-resources to manage the lifetime of off-heap memory\n try (Arena offHeap = Arena.ofConfined()) {\n // 4. Allocate a region of off-heap memory to store …Run Code Online (Sandbox Code Playgroud) 使用 java 21,只需在虚拟线程中执行即可将阻塞 IO 代码转换为非阻塞代码。
我应该简单地包装返回 an 的 HTTP 调用InputStream(如 method 中),还是在虚拟线程中nonBlockingA执行 the 的读取和反序列化(如 method 中)会更有效?InputStreamnonBlockingB
也就是说,读取是InputStream阻塞IO操作吗?
请记住,响应可能非常大,可能包含超过 500,000 个字符串。我也不确定所使用的库是否使用任何 ThreadLocals,这不推荐用于虚拟线程
@SuppressWarnings("unchecked")
class Request {
private final ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();
private CloseableHttpClient httpApacheClient;
List<String> nonBlockingA() throws Exception {
InputStream bigInputStream = executorService.submit(this::getResponse).get();
return deserialize(bigInputStream);
}
List<String> nonBlockingB() throws Exception {
return executorService.submit(() -> {
InputStream bigInputStream = getResponse();
return deserialize(bigInputStream);
}).get();
}
private InputStream getResponse() throws IOException {
return httpApacheClient.execute(new HttpGet("http://random/names/size/500000")).getEntity().getContent(); …Run Code Online (Sandbox Code Playgroud) 我正在使用 Spring Boot 3.1.5、 Java21和 maven 3.9.5。我运行时出现以下错误mvn spring-boot:build-image
[INFO] > Pulling builder image 'docker.io/paketobuildpacks/builder:base' 100%
[INFO] > Pulled builder image 'paketobuildpacks/builder@sha256:17ea21162ba8c7717d3ead3ee3836a368aced7f02f2e59658e52029bd6d149e7'
[INFO] > Pulling run image 'docker.io/paketobuildpacks/run:base-cnb' 100%
[INFO] > Pulled run image 'paketobuildpacks/run@sha256:1af9935d8987fd52b2266d288200c9482d1dd5529860bbf5bc2d248de1cb1a38'
[INFO] > Executing lifecycle version v0.16.5
[INFO] > Using build cache volume 'pack-cache-8847f704ad41.build'
[INFO]
[INFO] > Running creator
[INFO] [creator] ===> ANALYZING
[INFO] [creator] Image with name "docker.io/library/elevate-insights:0.0.1-SNAPSHOT" not found
[INFO] [creator] ===> DETECTING
[INFO] [creator] 6 of 26 buildpacks participating …Run Code Online (Sandbox Code Playgroud) 我刚刚将 Spring Boot 应用程序升级到 Java 21。作为其中的一部分,我还进行了更改以使用虚拟线程。无论是在服务 API 请求时还是在使用执行器在内部执行异步操作时。
对于一种用例,由虚拟线程驱动的执行器的性能似乎比ForkJoinPool由操作系统线程驱动的执行器差。此用例是设置一些 MDC 值并通过 HTTP调用外部系统。
这是我的伪代码:
List<...> ... = executorService.submit(
() -> IntStream.rangeClosed(-from, to)
.mapToObj(i -> ...)
.parallel()
.map(... -> {
try {
service.setSomeThreadLocalString(...);
MDC.put(..., ...);
MDC.put(..., ...);
return service.call(...);
} finally {
service.removeSomeThreadLocalString(...);
MDC.remove(...);
MDC.remove(...);
}
})
.toList())
.get();
Run Code Online (Sandbox Code Playgroud)
其中 ExecutorService 是:
new ForkJoinPool(30)Executors.newVirtualThreadPerTaskExecutor()看起来选项 1 的性能比选项 2 好很多。有时它比选项 1 快 100%。我在 Java 21 环境中完成了这个测试。我正在测试 10 个并行执行。其中选项 1 通常需要 800-1000 毫秒,选项 2 通常需要 1500-2000 毫秒。
如果有任何区别,请在 Spring …
我在java 21中看到,你不需要在你的main方法中编写public static,你可以只写
public class Main{
void main(String[] args){
System.out.println("Hi");
}
}
Run Code Online (Sandbox Code Playgroud)
我卸载了 java 17 并安装了 java 21 ,将其添加到环境变量中,但是当我运行此代码时,出现此错误。
Error: Main method not found in class Main, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
]
Run Code Online (Sandbox Code Playgroud)
当我在 cmd 中编写 java --version 时,我得到的 java 版本为 21 但代码仍然无法编译
java-21 ×10
java ×8
project-loom ×2
buildpack ×1
collections ×1
enumset ×1
generics ×1
inputstream ×1
java-ffm ×1
jdbi ×1
nonblocking ×1
sequencedset ×1
spring-boot ×1
thread-local ×1