写在前面
-
spring boot 3 已经提供了对虚拟线程的支持。
-
虚拟线程和平台线程主要区别在于,虚拟线程在运行周期内不依赖操作系统线程:它们与硬件脱钩,因此被称为 “虚拟”。这种解耦是由 JVM 提供的抽象层赋予的。
-
虚拟线程的运行成本远低于平台线程。消耗的内服务器托管网存要少得多。这就是为什么可以创建数百万个虚拟线程而不会出现内存不足的问题,而标准平台(或内核)线程只能创建数百个。
-
虚拟线程会优先使用JVM提供,如果不能使用JVM提供,则考虑使用由平台线程支持的“虚拟线程” ,相关源代码参考
java.lang.ThreadBuilders#newVirtualThread
版本要求
- spring boot 3.2.0
- jdk 21
pom.xml
project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
modelVersion>4.0.0modelVersion>
parent>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-parentartifactId>
version>3.2.0version>
relativePath/>
parent>
groupId>net.jlxxwgroupId>
artifactId>boot3-demoartifactId>
version>1.0.0.20231128version>
name>boot3-demoname>
description>boot3-demodescription>
properties>
java.version>21java.version>
project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
spring-boot.version>3.2.0spring-boot.version>
properties>
dependencies>
dependency>
groupId>org.apache.httpcomponents.client5groupId>
artifactId>httpclient5-fluentartifactId>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-aopartifactId>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-configuration-processorartifactId>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-loggingartifactId>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
dependency>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-testartifactId>
scope>testscope>
dependency>
dependencies>
build>
plugins>
plugin>
groupId>org.graalvm.buildtoolsgroupId>
artifactId>native-maven-pluginartifactId>
configuration>
imageName>${project.artifactId}imageName>
configuration>
plugin>
plugin>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
yml
spring:
#启动虚拟线程的必须配置
threads:
virtual:
# 启用虚拟线程技术,增加系统并发能力
enabled: true
自动装配解析
Tomcat 虚拟线程自动配置类
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration.TomcatWebServerFactoryCustomizerConfiguration#tomcatVirtualThreadsProtocolHandlerCustomizer
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.web.embedded;
import io.undertow.Undertow;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.UpgradeProtocol;
import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Loader;
import org.xnio.SslClientAuthMode;
import reactor.netty.http.server.HttpServer;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment;
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.thread.Threading;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
/**
* {@link EnableAutoConfiguration Auto-configuration} for embedded servlet and reactive
* web servers customizations.
*
* @author Phillip Webb
* @since 2.0.0
*/
@AutoConfiguration
@ConditionalOnNotWarDeployment
@ConditionalOnWebApplication
@EnableConfigurationProperties(ServerProperties.class)
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {
/**
* Nested configuration if Tomcat is being used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
public static class TomcatWebServerFactoryCustomizerConfiguration {
@Bean
public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment,
ServerProperties serverProperties) {
return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
}
@Bean
@ConditionalOnThreading(Threading.VIRTUAL)
TomcatVirtualThreadsWebServerFactoryCustomizer tomcatVirtualThreadsProtocolHandlerCustomizer() {
return new TomcatVirtualThreadsWebServerFactoryCustomizer();
}
}
/**
* Nested configuration if Jetty is being used.
*/
@Configuration(proxyBeanMeth服务器托管网ods = false)
@ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class })
public static class JettyWebServerFactoryCustomizerConfiguration {
@Bean
public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment,
ServerProperties serverProperties) {
return new JettyWebServerFactoryCustomizer(environment, serverProperties);
}
@Bean
@ConditionalOnThreading(Threading.VIRTUAL)
JettyVirtualThreadsWebServerFactoryCustomizer jettyVirtualThreadsWebServerFactoryCustomizer(
ServerProperties serverProperties) {
return new JettyVirtualThreadsWebServerFactoryCustomizer(serverProperties);
}
}
/**
* Nested configuration if Undertow is being used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Undertow.class, SslClientAuthMode.class })
public static class UndertowWebServerFactoryCustomizerConfiguration {
@Bean
public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment,
ServerProperties serverProperties) {
return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
}
}
/**
* Nested configuration if Netty is being used.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HttpServer.class)
public static class NettyWebServerFactoryCustomizerConfiguration {
@Bean
public NettyWebServerFactoryCustomizer nettyWebServerFactoryCustomizer(Environment environment,
ServerProperties serverProperties) {
return new NettyWebServerFactoryCustomizer(environment, serverProperties);
}
}
}
Tomcat虚拟线程定制器
org.springframework.boot.autoconfigure.web.embedded.TomcatVirtualThreadsWebServerFactoryCustomizer
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.web.embedded;
import org.apache.coyote.ProtocolHandler;
import org.apache.tomcat.util.threads.VirtualThreadExecutor;
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.core.Ordered;
/**
* Activates {@link VirtualThreadExecutor} on {@link ProtocolHandler Tomcat's protocol
* handler}.
*
* @author Moritz Halbritter
* @since 3.2.0
*/
public class TomcatVirtualThreadsWebServerFactoryCustomizer
implements WebServerFactoryCustomizerConfigurableTomcatWebServerFactory>, Ordered {
@Override
public void customize(ConfigurableTomcatWebServerFactory factory) {
factory.addProtocolHandlerCustomizers(
(protocolHandler) -> protocolHandler.setExecutor(new VirtualThreadExecutor("tomcat-handler-")));
}
@Override
public int getOrder() {
return TomcatWebServerFactoryCustomizer.ORDER + 1;
}
}
新的虚拟线程池
org.apache.tomcat.util.threads.VirtualThreadExecutor
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.tomcat.util.threads;
import java.util.concurrent.Executor;
import org.apache.tomcat.util.compat.JreCompat;
/**
* An executor that uses a new virtual thread for each task.
*/
public class VirtualThreadExecutor implements Executor {
private final JreCompat jreCompat = JreCompat.getInstance();
private Object threadBuilder;
public VirtualThreadExecutor(String namePrefix) {
threadBuilder = jreCompat.createVirtualThreadBuilder(namePrefix);
}
@Override
public void execute(Runnable command) {
jreCompat.threadBuilderStart(threadBuilder, command);
}
}
测试对比效果
启用虚拟线程
未启用虚拟线程
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
本文主要展示常见的肌电信号特征的提取说明。使用python 环境下的Pysiology计算库。 目录 1 肌电信号第一次burst的振幅, getAFP 函数 2 肌电信号波长的标准差计算,getDASDV函数 3 肌电信号功率谱频率比例,getFR函数 4 …