简体   繁体   English

由两个线程访问的同步块

[英]Synchronized block accessed by two threads

I have a synchronized method that is being called from a controller method. 我有一个从控制器方法中调用的同步方法。 When two request access this only one should go through and other should be blocked until first is finished. 当有两个请求访问时,只有一个应通过,其他应被阻止直到第一个完成。

But when the incoming requests are fast, this is actually returning same accountId to two different requests, which is not intended. 但是,当传入的请求很快时,这实际上是将相同的accountId返回两个不同的请求,这不是故意的。

Please help me understand how do I synchronize this getNextAccount() call so that it only return one account to one request. 请帮助我了解如何同步此getNextAccount()调用,以便它仅将一个帐户返回到一个请求。

Method in AccService.java 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(){...}

A synchronized block will only give you mutual exclusion if the threads are on the same host, and if they are locking using the same lock object. 如果线程在同一主机上并且使用相同的锁对象进行锁定,则synchronized块将仅使您相互排斥。

Based on what you originally wrote in your question, it seems that one or both of these preconditions is not satisfied. 根据您最初在问题中所写的内容,似乎这些先决条件中的一个或两个都不满足。 If (as it now transpires) there is only one host processing these requests, then we must consider the other possibility; 如果(现在发生)只有一个主机在处理这些请求,那么我们必须考虑另一种可能性; ie that there multiple instances of the AccService object processing requests. 即存在AccService对象处理请求的多个实例。

It is also possible that synchronization is working, and the problem is somewhere else. 同步也可能起作用,而问题出在其他地方。 For example, getAccount() could be returning the same account on successive calls. 例如, getAccount()可能在连续调用中返回相同的帐户。


Basically, there are too many parts of your code-base that we can't see. 基本上,您的代码库中有太多我们看不到的部分。 This means that we can only theorize as to what is causing the problem. 这意味着我们只能对导致问题的原因进行理论化。 If every thing was done correctly; 如果每件事都做得正确; ie

  • there is only one host, 只有一个主机,
  • all threads are sharing the same lock object, 所有线程共享同一个锁对象,
  • getAccount() is implemented correctly, and getAccount()的实现正确,并且
  • nothing else updates the account state used by getAccount without proper synchronization, 在没有正确同步的情况下,没有其他任何事情可以更新getAccount所使用的帐户状态,

then the code you have shown us would work. 那么您向我们展示的代码就会起作用。

If you need more help, an MCVE is probably required. 如果您需要更多帮助,则可能需要MCVE。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 两个线程进入一个同步块 - Two threads enter a synchronized block Swing 中两个线程上的同步块不起作用 - Synchronized block on two threads in Swing not working 两个线程同时执行同步块 - Two threads executing synchronized block simultaneously 如何通过Junit测试两个线程无法同时访问的同步对象? - How to Junit test a synchronized object not accessed by two threads at same time? 同步两个线程不同步 - Synchronized two threads not working synchronized 通过更改运行时监视器将两个线程放入同步块 - Two threads into synchronized block by changing monitor in run time 两个线程如何同时进入同步块? - How could the two threads enter the synchronized block at the same time? 需要代码来理解同步的 static 和同一实例上的两个不同线程同时访问的非静态方法 - Need code to understand synchronized static and non-static methods being accessed at the same time by two different threads on the same instance 如果两个线程使用不同的监视器,是否可以在同一个 object 上执行相同的同步代码块? - Can two threads execute the same synchronized block of code on the same object if they use different monitors? 同步块中的操作是否对其他线程可见? - Are actions in a synchronized block visible to other threads?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM