Java:如果另一个线程已经在其中,则新线程将跳过同步方法

标签 java spring multithreading

要求

  1. 我需要能够通过 POST 调用触发(长时间运行的)作业并立即返回。

  2. 一次只能有一个线程运行作业。

  3. 这项工作是一项昂贵的工作,如果一项工作已经在进行中,我希望这项工作的所有 future 触发器都不做任何事情。

代码

@RestController
public class SomeTask {

    private SomeService someService;

    @Autowired
    public SomeTask(SomeService someService) {
        this.someService = someService;
    }

    @Async // requirement 1
    @RequestMapping(method = RequestMethod.POST, path = "/triggerJob")
    public void triggerJob() {
        expensiveLongRunningJob();
    }

    /**
     * Synchronized in order to restrict multiple invocations. // requirement 2
     *
     */
    private synchronized void expensiveLongRunningJob() { 
        someService.executedJob();
    }
}

问题

通过上述代码,满足了要求 1 和 2。满足要求 3 的最佳方法是什么(让作为 POST 调用的结果创建的新线程跳过同步方法并在获取锁失败时立即返回)?

最佳答案

同步不是完成这项工作的正确工具。你可以这样做:

@RestController
public class SomeTask {

    private SomeService someService;
    private final AtomicBoolean isTriggered = new AtomicBoolean();

    @Autowired
    public SomeTask(SomeService someService) {
        this.someService = someService;
    }

    @Async // requirement 1
    @RequestMapping(method = RequestMethod.POST, path = "/triggerJob")
    public void triggerJob() {
        if (!isTriggered.getAndSet(true)) {
            try {
                expensiveLongRunningJob();
            } finally {
                isTriggered.set(false);
            }
        }
    }

    /**
     * only runs once at a time, in the thread that sets isTriggered to true
     */
    private void expensiveLongRunningJob() { 
        someService.executedJob();
    }
}

关于Java:如果另一个线程已经在其中,则新线程将跳过同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56776981/

相关文章:

spring - HQL - 使用 H2 和 MySQL 在 where 子句中列出可以为空的列表

Java : threads are limited to 25% of the CPU

java - 在 GWT 启动时启动后台线程

java - 如何检测/建议 Spring Data (JPA) 存储库?

Spring 在没有 @Autowired 注释的构造函数中注入(inject)依赖项

c++ - OpenMP自动更新数组值

java - 是否可以从多个枚举中通过字符串获取枚举值?

java - 自定义 jackson bean 序列化器,可以根据同级属性的值动态忽略一些带注释的属性

java.util.regex.PatternSyntaxException 安卓

java - 调整 JFrame 大小时会调用哪些方法?