From 46397381ba3835f65e8ef881e83bd36d53f76996 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Thu, 14 Sep 2023 10:33:34 +0800 Subject: [PATCH] Eliminate synchronized block to avoid thread pinning in SingletonSupplier --- .../util/function/SingletonSupplier.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/function/SingletonSupplier.java b/spring-core/src/main/java/org/springframework/util/function/SingletonSupplier.java index cf63e6c34fc7..b4f71954d87f 100644 --- a/spring-core/src/main/java/org/springframework/util/function/SingletonSupplier.java +++ b/spring-core/src/main/java/org/springframework/util/function/SingletonSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-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. @@ -16,6 +16,8 @@ package org.springframework.util.function; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; import org.springframework.lang.Nullable; @@ -31,6 +33,7 @@ * supplier for a method that returned {@code null} and caching the result. * * @author Juergen Hoeller + * @author Yanming Zhou * @since 5.1 * @param the type of results supplied by this supplier */ @@ -45,6 +48,11 @@ public class SingletonSupplier implements Supplier { @Nullable private volatile T singletonInstance; + /** + * Guards access to write operations on the response. + */ + private final Lock writeLock = new ReentrantLock(); + /** * Build a {@code SingletonSupplier} with the given singleton instance @@ -90,7 +98,8 @@ private SingletonSupplier(T singletonInstance) { public T get() { T instance = this.singletonInstance; if (instance == null) { - synchronized (this) { + this.writeLock.lock(); + try { instance = this.singletonInstance; if (instance == null) { if (this.instanceSupplier != null) { @@ -102,6 +111,9 @@ public T get() { this.singletonInstance = instance; } } + finally { + this.writeLock.unlock(); + } } return instance; }