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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user