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
This commit is contained in:
Moritz Halbritter 2023-08-10 11:34:18 +02:00
parent bcee354f54
commit fbd3b65034
1 changed files with 14 additions and 4 deletions

View File

@ -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;