在现代高并发Java应用中,传统的单例实现方式(如DCL双重检查锁定)虽然解决了线程安全问题,但仍存在以下局限性:
public class ThreadLocalSingleton {
private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance =
ThreadLocal.withInitial(ThreadLocalSingleton::new);
private ThreadLocalSingleton() {
// 私有构造函数
}
public static ThreadLocalSingleton getInstance() {
return threadLocalInstance.get();
}
// 清理线程局部变量,避免内存泄漏
public static void remove() {
threadLocalInstance.remove();
}
}
优势:
适用场景:
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
public class VarHandleSingleton {
private static final VarHandle INSTANCE;
private static VarHandleSingleton instance;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
INSTANCE = l.findStaticVarHandle(VarHandleSingleton.class, "instance", VarHandleSingleton.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
}
private VarHandleSingleton() {
// 私有构造函数
}
public static VarHandleSingleton getInstance() {
VarHandleSingleton result = (VarHandleSingleton) INSTANCE.getAcquire();
if (result != null) {
return result;
}
result = new VarHandleSingleton();
if (INSTANCE.compareAndSet(null, result)) {
return result;
}
return (VarHandleSingleton) INSTANCE.getAcquire();
}
}
优势:
适用场景:
import java.util.concurrent.atomic.AtomicReference;
public record RecordSingleton(String config) {
private static final AtomicReference<RecordSingleton> INSTANCE = new AtomicReference<>();
public static RecordSingleton getInstance() {
return INSTANCE.updateAndGet(current ->
current != null ? current : new RecordSingleton("defaultConfig"));
}
// 可选:提供配置更新方法
public static RecordSingleton updateConfig(String newConfig) {
return INSTANCE.updateAndGet(current ->
current != null ? new RecordSingleton(newConfig) : new RecordSingleton(newConfig));
}
}
优势:
适用场景:
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
public class ReactiveSingleton {
private static final Mono<ReactiveSingleton> INSTANCE = Mono.fromCallable(ReactiveSingleton::new)
.subscribeOn(Schedulers.boundedElastic())
.cache(); // 缓存结果,确保只创建一次
private ReactiveSingleton() {
// 私有构造函数
// 模拟耗时初始化
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public static Mono<ReactiveSingleton> getInstance() {
return INSTANCE;
}
// 示例方法
public Mono<String> process(String data) {
return Mono.just(data.toUpperCase());
}
}
优势:
适用场景:
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Singleton;
@Singleton // 或使用 @ApplicationScoped (Jakarta EE)
public class CdiSingleton {
private int counter = 0;
public synchronized int incrementAndGet() {
return ++counter;
}
// 业务方法
public String doBusinessLogic() {
return "Business logic executed with counter: " + counter;
}
}
优势:
适用场景:
以下是使用JMH框架进行的性能测试代码示例:
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 5, time = 1)
@Fork(1)
@State(Scope.Benchmark)
public class SingletonBenchmark {
@Benchmark
public void enumSingleton(Blackhole bh) {
bh.consume(EnumSingleton.INSTANCE);
}
@Benchmark
public void staticInnerClassSingleton(Blackhole bh) {
bh.consume(StaticInnerClassSingleton.getInstance());
}
@Benchmark
public void varHandleSingleton(Blackhole bh) {
bh.consume(VarHandleSingleton.getInstance());
}
@Benchmark
public void recordSingleton(Blackhole bh) {
bh.consume(RecordSingleton.getInstance());
}
@Benchmark
public void reactiveSingleton(Blackhole bh) throws Exception {
ReactiveSingleton.getInstance()
.block(); // 实际应用中应使用响应式方式处理
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(SingletonBenchmark.class.getSimpleName())
.build();
new Runner(opt).run();
}
}
典型的测试结果表明,在高并发场景下,基于VarHandle的实现通常比传统的DCL和枚举单例有5-10%的性能提升,而响应式单例在异步场景下表现最佳。
下面是一个结合多种现代技术的高性能配置中心实现:
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
public class ConfigCenter {
// 使用AtomicReference确保无锁更新
private static final AtomicReference<ConfigCenter> INSTANCE = new AtomicReference<>();
// 使用ConcurrentHashMap存储配置项
private final Map<String, Object> configs = new ConcurrentHashMap<>();
// 私有构造函数
private ConfigCenter() {
// 从配置源加载初始配置
loadDefaultConfigs();
}
// 无锁单例获取方法
public static ConfigCenter getInstance() {
return INSTANCE.updateAndGet(current ->
current != null ? current : new ConfigCenter());
}
// 加载默认配置
private void loadDefaultConfigs() {
// 从文件、数据库或远程服务加载配置
configs.put("app.name", "HighPerformanceApp");
configs.put("max.connections", 100);
configs.put("timeout.seconds", 30);
}
// 获取配置项
@SuppressWarnings("unchecked")
public <T> T getConfig(String key) {
return (T) configs.get(key);
}
// 获取配置项,不存在时使用默认值
@SuppressWarnings("unchecked")
public <T> T getConfig(String key, T defaultValue) {
return (T) configs.getOrDefault(key, defaultValue);
}
// 动态配置获取,支持延迟初始化
@SuppressWarnings("unchecked")
public <T> T getConfig(String key, Supplier<T> defaultSupplier) {
return (T) configs.computeIfAbsent(key, k -> defaultSupplier.get());
}
// 更新配置
public void updateConfig(String key, Object value) {
configs.put(key, value);
}
// 批量更新配置
public void updateConfigs(Map<String, Object> newConfigs) {
configs.putAll(newConfigs);
}
}
这个配置中心实现了:
通过采用现代无锁技术实现单例模式,可以在保证线程安全的同时显著提升应用性能,特别是在高并发环境下。随着Java语言的不断发展,未来还会有更多高效的单例实现方式出现。
Java, 无锁编程,高性能,线程,并发控制,原子操作,ConcurrentHashMap,CopyOnWriteArrayList,AtomicInteger,LongAdder,CAS, 乐观锁,非阻塞算法,线程安全,并发实战
代码获取方式
https://pan.quark.cn/s/14fcf913bae6
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。