在我的项目中,当我同时调用同一个请求的属性时,我们使用带有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对象?
任何帮助都会得到极大的赞赏!!!!
答案 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 。