java - 两个线程访问的同步块(synchronized block)

标签 java synchronization

我有一个从 Controller 方法调用的同步方法。 当两个请求访问时,只有一个应该通过,其他的应该被阻止,直到第一个请求完成。

但是当传入请求很快时,这实际上是向两个不同的请求返回相同的 accountId,这不是我们想要的。

请帮助我了解如何同步此 getNextAccount() 调用,以便它只向一个请求返回一个帐户。

AccService.java中的方法

private final Object lockObject = new Object();
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Long getNextAccount(String hostport) {
    synchronized (lockObject) {

        Long acc = null;
        try {
            AccountFetch dtls = getAccount();
            if (dtls != null) {
                acc = dtls.getAccId();

                //Set IN_PROGRESS 
                dtls.setStatus("Progress");
                dtls.saveAndFlush(dtls);
                return acc;
            } else {
                log.info("No More Accounts to Process");
            }
        } catch (Exception e) {

            e.getStackTrace();
        }
        return acc;
    }
}

@Autowired
private AccService accSevice;
@GET
@Path("/accprocess")
@Produces(MediaType.APPLICATION_JSON)
public AccountFetch getAccId(@QueryParam("currentHost") final String currentHost,
        @QueryParam("currentPort") final String currentPort) {
    AccountFetch dtls = new AccountFetch();
    try {
        Long batchId = accSevice. getNextAccount(currentHost+"#"+currentPort);
        if (accId != null) {
            dtls.setAccId(String.valueOf(accId));
        } else {
            dtls.setAccId(BLANK_STRING);
        }
    } catch (Exception e) {
        log.error("Exception while getting accId : " + e.getMessage());
    }
    return dtls;
}

public AccountFetch getAccount(){...}

最佳答案

只有当线程位于同一主机上并且使用相同的锁对象进行锁定时,synchronized block 才会提供互斥。

根据您最初在问题中所写的内容,似乎不满足这些先决条件之一或两个。如果(正如现在所发生的那样)只有一台主机处理这些请求,那么我们必须考虑另一种可能性;即有多个 AccService 对象实例处理请求。

也有可能同步正在工作,但问题出在其他地方。例如,getAccount() 可能会在连续调用时返回相同的帐户。

<小时/>

基本上,您的代码库中有太多我们看不到的部分。这意味着我们只能对导致问题的原因进行理论分析。如果每件事都做对了;即

  • 只有一台主机,
  • 所有线程共享同一个锁对象,
  • getAccount() 已正确实现,并且
  • 如果没有正确的同步,则不会更新 getAccount 使用的帐户状态,

那么您向我们展示的代码将会工作。

如果您需要更多帮助,可能需要 MCVE。

关于java - 两个线程访问的同步块(synchronized block),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49345622/

相关文章:

java jasypt 突然崩溃

c - P线程同步: Back & Forth Reading of Two Text Files

time - 如何考虑分布式系统中的时钟偏移?

windows - 为什么 WaitForSingleObject(INVALID_HANDLE_VALUE, INFINITE) 会阻塞?

java - 为什么 -XX :+UseCompressedOops not defaulted, 并不总是被使用?

java - 在 Java 中调用静态对象的方法会评估一些不正确的值

Java HashMap : How to modify the output of the matrix?

java - 在 hibernate 搜索中关闭索引

java - 同步 SynchronizedMap 的性能开销

multithreading - 仅按需从 TThread 动态初始化和调用 LoadLibrary 一次