Replace synchronized blocks and methods with locks

This commit replaces synchronized blocks and methods
that are used frequently or that guard blocking I/O
operations with locks. This is required to prevent
virtual threads pinning, as explained in JEP 444 [1].

Note that synchronized blocks and methods that are used
infrequently (like AutomaticJobRegistrar#start/stop) or
that guard in-memory operations were not replaced as this
is not required, see JEP 444 [1].

Resolves to #4399

---
[1]: https://openjdk.org/jeps/444
This commit is contained in:
Mahmoud Ben Hassine
2023-07-15 08:18:07 +02:00
parent 05168089f1
commit 5bccfed523
11 changed files with 144 additions and 26 deletions

View File

@@ -30,6 +30,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
@@ -112,6 +114,8 @@ public class JdbcExecutionContextDao extends AbstractJdbcBatchMetadataDao implem
private ExecutionContextSerializer serializer = new DefaultExecutionContextSerializer();
private final Lock lock = new ReentrantLock();
/**
* Setter for {@link Serializer} implementation
* @param serializer {@link ExecutionContextSerializer} instance to use.
@@ -191,7 +195,8 @@ public class JdbcExecutionContextDao extends AbstractJdbcBatchMetadataDao implem
public void updateExecutionContext(final StepExecution stepExecution) {
// Attempt to prevent concurrent modification errors by blocking here if
// someone is already trying to do it.
synchronized (stepExecution) {
this.lock.lock();
try {
Long executionId = stepExecution.getId();
ExecutionContext executionContext = stepExecution.getExecutionContext();
Assert.notNull(executionId, "ExecutionId must not be null.");
@@ -201,6 +206,9 @@ public class JdbcExecutionContextDao extends AbstractJdbcBatchMetadataDao implem
persistSerializedContext(executionId, serializedContext, UPDATE_STEP_EXECUTION_CONTEXT);
}
finally {
this.lock.unlock();
}
}
@Override

View File

@@ -26,6 +26,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -158,6 +160,8 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements
private ConfigurableConversionService conversionService;
private final Lock lock = new ReentrantLock();
public JdbcJobExecutionDao() {
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new DateToStringConverter());
@@ -278,7 +282,8 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements
Assert.notNull(jobExecution.getVersion(),
"JobExecution version cannot be null. JobExecution must be saved before it can be updated");
synchronized (jobExecution) {
this.lock.lock();
try {
Integer version = jobExecution.getVersion() + 1;
String exitDescription = jobExecution.getExitStatus().getExitDescription();
@@ -323,6 +328,9 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements
jobExecution.incrementVersion();
}
finally {
this.lock.unlock();
}
}
@Nullable

View File

@@ -26,6 +26,8 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -119,6 +121,8 @@ public class JdbcStepExecutionDao extends AbstractJdbcBatchMetadataDao implement
private DataFieldMaxValueIncrementer stepExecutionIncrementer;
private final Lock lock = new ReentrantLock();
/**
* Public setter for the exit message length in database. Do not set this if you
* haven't modified the schema.
@@ -256,7 +260,8 @@ public class JdbcStepExecutionDao extends AbstractJdbcBatchMetadataDao implement
// Attempt to prevent concurrent modification errors by blocking here if
// someone is already trying to do it.
synchronized (stepExecution) {
this.lock.lock();
try {
Integer version = stepExecution.getVersion() + 1;
Timestamp startTime = stepExecution.getStartTime() == null ? null
@@ -289,6 +294,9 @@ public class JdbcStepExecutionDao extends AbstractJdbcBatchMetadataDao implement
stepExecution.incrementVersion();
}
finally {
this.lock.unlock();
}
}
/**