From fbd3b65034637ab2ac1b3de264d9a5600e4129dd Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Thu, 10 Aug 2023 11:34:18 +0200 Subject: [PATCH] Refactor synchronized to Lock in ApplicationTemp The synchronized guards an I/O operation. Additionally, this adds double-checked locking to the path instance field. See gh-36670 --- .../boot/system/ApplicationTemp.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/ApplicationTemp.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/ApplicationTemp.java index 9c413a0ab7..2ab9f745f5 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/ApplicationTemp.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/ApplicationTemp.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * 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. @@ -28,6 +28,8 @@ import java.nio.file.attribute.PosixFilePermissions; import java.security.MessageDigest; import java.util.EnumSet; import java.util.HexFormat; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -49,6 +51,8 @@ public class ApplicationTemp { private final Class sourceClass; + private final Lock pathLock = new ReentrantLock(); + private volatile Path path; /** @@ -90,9 +94,15 @@ public class ApplicationTemp { private Path getPath() { if (this.path == null) { - synchronized (this) { - String hash = HexFormat.of().withUpperCase().formatHex(generateHash(this.sourceClass)); - this.path = createDirectory(getTempDirectory().resolve(hash)); + this.pathLock.lock(); + try { + if (this.path == null) { + String hash = HexFormat.of().withUpperCase().formatHex(generateHash(this.sourceClass)); + this.path = createDirectory(getTempDirectory().resolve(hash)); + } + } + finally { + this.pathLock.unlock(); } } return this.path;