// 场景1:状态检查和更新不是原子操作,导致竞态条件
public class RaceConditionBug {
private volatile TaskState state = TaskState.PENDING;
// 问题代码
public void processTaskWithBug(String taskId) {
// 检查和更新之间可能有其他线程修改状态
if (state == TaskState.PENDING) {
// 这里可能被其他线程中断
Thread.sleep(100); // 模拟一些处理
state = TaskState.RUNNING; // 状态可能已经被其他线程改变
}
}
// 修复方案:使用同步块
public void processTaskFixed(String taskId) {
synchronized (this) {
if (state == TaskState.PENDING) {
state = TaskState.RUNNING;
}
}
}
}
// 场景2:事件处理顺序依赖导致的问题
public class EventOrderingBug {
private BlockingQueue<StateEvent> eventQueue = new LinkedBlockingQueue<>();
private volatile TaskState state = TaskState.PENDING;
// 问题代码
public void handleEventsWithBug() {
executor.submit(() -> {
StateEvent event1 = eventQueue.take();
processEvent(event1); // 处理第一个事件
});
executor.submit(() -> {
StateEvent event2 = eventQueue.take();
processEvent(event2); // 可能在event1之前处理
});
}
// 修复方案:使用单线程处理保证顺序
private final ExecutorService singleThreadExecutor =
Executors.newSingleThreadExecutor();
public void handleEventsFixed() {
singleThreadExecutor.submit(() -> {
while (true) {
StateEvent event = eventQueue.take();
processEvent(event); // 按队列顺序处理
}
});
}
}
// 场景3:状态转换过程中的中断问题
public class StateTransitionBug {
private Lock stateLock = new ReentrantLock();
private TaskState state = TaskState.PENDING;
// 问题代码
public void transitWithBug(TaskState newState) {
try {
stateLock.lock();
validateTransition(state, newState); // 可能抛出异常
updateState(newState); // 如果上面抛异常,状态可能不一致
} finally {
stateLock.unlock();
}
}
// 修复方案:使用事务性的状态转换
@Transactional
public void transitFixed(TaskState newState) {
TaskEntity task = taskRepository.findById(taskId)
.orElseThrow(() -> new TaskNotFoundException(taskId));
validateTransition(task.getState(), newState);
task.setState(newState);
taskRepository.save(task);
publishStateChangeEvent(task);
}
}
// 场景4:非幂等的状态转换
public class NonIdempotentBug {
// 问题代码
public void completeTaskWithBug(String taskId) {
TaskEntity task = taskRepository.findById(taskId).get();
task.setState(TaskState.COMPLETED);
task.setCompletionCount(task.getCompletionCount() + 1); // 多次调用会累加
taskRepository.save(task);
}
// 修复方案:实现幂等性
public void completeTaskFixed(String taskId) {
taskRepository.updateTaskState(
taskId,
TaskState.RUNNING, // 预期的当前状态
TaskState.COMPLETED // 目标状态
);
}
}
// 场景5:分布式环境下的状态同步问题
public class DistributedStateBug {
// 问题代码
public void processDistributedTaskWithBug(String taskId) {
TaskEntity task = taskRepository.findById(taskId).get();
if (task.getState() == TaskState.PENDING) {
// 其他节点可能已经在处理
task.setState(TaskState.RUNNING);
taskRepository.save(task);
}
}
// 修复方案:使用分布式锁
private final DistributedLock distributedLock;
public void processDistributedTaskFixed(String taskId) {
try {
if (distributedLock.tryLock(taskId, 5, TimeUnit.SECONDS)) {
try {
TaskEntity task = taskRepository.findById(taskId).get();
if (task.getState() == TaskState.PENDING) {
task.setState(TaskState.RUNNING);
taskRepository.save(task);
}
} finally {
distributedLock.unlock(taskId);
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new TaskProcessingException("Failed to acquire lock", e);
}
}
}
// 场景6:状态转换的一致性问题
public class StateConsistencyBug {
// 问题代码
public void updateRelatedStatesWithBug(String taskId) {
// 更新主任务状态
TaskEntity task = taskRepository.findById(taskId).get();
task.setState(TaskState.COMPLETED);
taskRepository.save(task);
// 更新子任务状态可能失败
List<SubTaskEntity> subTasks = subTaskRepository.findByParentId(taskId);
for (SubTaskEntity subTask : subTasks) {
subTask.setState(TaskState.COMPLETED);
subTaskRepository.save(subTask); // 可能抛出异常
}
}
// 修复方案:使用事务确保一致性
@Transactional
public void updateRelatedStatesFixed(String taskId) {
TaskEntity task = taskRepository.findById(taskId).get();
List<SubTaskEntity> subTasks = subTaskRepository.findByParentId(taskId);
// 在一个事务中更新所有相关状态
task.setState(TaskState.COMPLETED);
taskRepository.save(task);
for (SubTaskEntity subTask : subTasks) {
subTask.setState(TaskState.COMPLETED);
subTaskRepository.save(subTask);
}
}
}
标签:task,taskRepository,void,TaskState,偶发性,状态机,public,taskId,bug
From: https://blog.csdn.net/qq_51149892/article/details/144988109