并发请求中的rest api数据不匹配

时间:2018-01-30 10:41:04

标签: java spring rest concurrency

在我的项目中,当我同时调用同一个请求的属性时,我们使用带有spring框架的restful webservices 对象被彼此覆盖。

以下是我的代码。

@Service("testService")
@Scope(value ="prototype")
public class TestServiceImpl extends DefaultServiceBuilder {

        public void test() {
                 process();
                 System.err.println(tranLog.getTxnId());

        }
}


  public class DefaultServiceBuilder {

protected TransactionLog tranLog;

public void process() {
    tranLog = new TransactionLog();
    Random r = new Random();
    String rid = r.nextInt(40000)+"";
    tranLog.setTxnid(rid);
    setTranLog(tranLog);
}


    public TransactionLog getTranLog() {
        return tranLog;
    }

    public void setTranLog(TransactionLog tranLog) {
        this.tranLog = tranLog;
    }
}

public class TransactionLog {
   private String txnId;

   public void setTxnId(String txnId) {
        this.txnId = txnId;
   }

   public String getTxnId() {
        return txnId;
   }
}

我用2个线程并行调用以下请求。

My expected input is 
123456
242422

But the output is 
242422
242422

为什么TransactionLog对象值会覆盖eventHough,尽管我给了范围原型。 如何安全地访问Transalog对象?

任何帮助都会得到极大的赞赏!!!!

2 个答案:

答案 0 :(得分:1)

您可以通过同步以下代码行来同步您的代码

protected static TransactionLog tranLog;

public static synchronized void process() {
    Random r = new Random();
    tranLog = new TransactionLog();
    String rid = r.nextInt(40000)+"";
    tranLog.setTxnid(rid);
}

使static synchronized在任何给定时间只允许一个线程。

答案 1 :(得分:1)

类名 TransactionLog 意味着 TransactionLog 的evety实例,写入变量 tranLog 只会在一个线程中使用。

如果是的话,请进一步阅读:

在非常好的书中,“Java Concurrency in Practice”描述了一种良好的线程同步模式:

  

线程限制

     

访问共享的可变数据需要使用同步;避免这种要求的一种方法是不共享。如果仅从单个线程访问数据,则不需要同步。这种技术,线程限制,是实现线程安全的最简单方法之一。当一个对象被限制在一个线程中时,即使受限对象本身不是[CPJ 2.3.2],这种用法也是自动线程安全的。

将字段 tranLog 设为本地变量

final TransactionLog tranLog = new TransactionLog();

如果您在其他功能中使用它,例如 subProcess2

private void subProcess2() {
    tranLog.doSometthing();
}

tranLog 添加到函数参数:

private void subProcess2(TransactionLog tranLog) {
    tranLog.doSometthing();
}

在调用 subProcess2 时传递 tranLog