gpt4 book ai didi

java - 长时间运行的方法会导致竞争条件

转载 作者:行者123 更新时间:2023-12-02 08:32:41 24 4
gpt4 key购买 nike

我对 hibernate 还比较陌生,所以请保持温柔。我在长时间运行的方法(约 2 分钟长)和更改存储在数据库中的对象上的状态字段的值时遇到问题。下面的伪代码应该有助于解释我的问题。

public foo(thing) {  
if (thing.getStatus() == "ready") {
thing.setStatus("finished");
doSomethingAndTakeALongTime();
} else {
// Thing already has a status of finished. Send the user back a message.
}
}

伪代码不需要太多解释。我希望 doSomethingAndTakeALongTime() 运行,但前提是它的状态为“就绪”。每当 doSomethingAndTakeALongTime() 完成需要 2 分钟并且事物状态字段的更改在离开 foo() 之前不会持久保存到数据库时,就会出现我的问题。因此,另一个用户可以在这 2 分钟内发出请求,if 语句将计算为 true。

我已经尝试过手动更新字段并刷新 session ,但似乎不起作用。我不知道从这里该怎么做,非常感谢任何帮助。

PS:我的 hibernate session 由 spring 管理。

最佳答案

基本上,您需要让它在单独的线程中运行,以使该方法立即返回。否则它确实会阻塞,直到长时间运行的任务完成。您可以将实体本身传递给线程,以便它可以自行更新状态。这是使用简单Thread的基本启动示例。

public class Task extends Thread {
private Entity entity;
public Task(Entity entity) {
this.entity = entity;
}
public void run() {
entity.setStatus(Status.RUNNING);
// ...
// Long running task here.
// ...
entity.setStatus(Status.FINISHED);
}
}

public synchronized void foo(Entity entity) {
if (entity.getStatus() == Status.READY) {
new Task(entity).start();
} else {
// ...
}
}

状态位于 enum 中您甚至可以使用 switch 语句来代替 if/else

    switch (entity.getStatus()) {
case READY:
new Task(entity).start();
break;
case RUNNING:
// It is still running .. Have patience!
break;
case FINISHED:
// It is finished!
break;
}

为了对正在运行的线程进行更强大的控制,您可能需要考虑 ExecutorService反而。由此,您可以控制最大线程数并指定超时。

关于java - 长时间运行的方法会导致竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2917156/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com