In my project we are using restful webservices with spring framework, when I call the same request concurrently the property of the object is overriden by one another.
在我的项目中,我们使用带有spring框架的restful webservices,当我同时调用相同的请求时,对象的属性被彼此覆盖。
Below is my code.
以下是我的代码。
@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;
}
}
I am calling the below request with 2 thread parallel.
我用2线程并行调用以下请求。
My expected input is
123456
242422
But the output is
242422
242422
Why the TransactionLog object value is overriding eventhough i gave scope prototype. How to access the Transalog object safely?
为什么TransactionLog对象值覆盖了尽管我给了范围原型。如何安全地访问Transalog对象?
Any help will be greatly Appreciated!!!!
任何帮助将不胜感激!!!!
2 个解决方案
#1
1
You could synchronize your code, by synchronizing below line of code
您可以通过同步下面的代码行来同步代码
protected static TransactionLog tranLog;
public static synchronized void process() {
Random r = new Random();
tranLog = new TransactionLog();
String rid = r.nextInt(40000)+"";
tranLog.setTxnid(rid);
}
Making static synchronized
will allow only one thread at any given time.
进行静态同步将在任何给定时间仅允许一个线程。
#2
1
Class name TransactionLog implies that evety instance of TransactionLog, writed to variable tranLog will be used only in one thread.
类名TransactionLog意味着TransactionLog的evety实例,写入变量tranLog只能在一个线程中使用。
If it right, then read further:
如果是的话,那就进一步阅读:
In very good book "Java Concurrency in Practice" described one good pattern of thread synchronization:
在非常好的书“Java Concurrency in Practice”中描述了一种良好的线程同步模式:
Thread Confinement
Accessing shared, mutable data requires using synchronization; one way to avoid this requirement is to not share. If data is only accessed from a single thread, no synchronization is needed. This technique, thread confinement, is one of the simplest ways to achieve thread safety. When an object is confined to a thread, such usage is automatically thread-safe even if the confined object itself is not [CPJ 2.3.2].
访问共享的可变数据需要使用同步;避免这种要求的一种方法是不分享。如果仅从单个线程访问数据,则不需要同步。这种技术,线程限制,是实现线程安全的最简单方法之一。当一个对象局限于一个线程时,即使受限对象本身不是[CPJ 2.3.2],这种用法也是自动线程安全的。
Make field tranLog just local variable
使字段tranLog只是局部变量
final TransactionLog tranLog = new TransactionLog();
If you use it in other function, for instance subProcess2:
如果您在其他函数中使用它,例如subProcess2:
private void subProcess2() {
tranLog.doSometthing();
}
Add tranLog to function parameters:
将tranLog添加到函数参数:
private void subProcess2(TransactionLog tranLog) {
tranLog.doSometthing();
}
And pass tranLog when calling subProcess2.
并在调用subProcess2时传递tranLog。
#1
1
You could synchronize your code, by synchronizing below line of code
您可以通过同步下面的代码行来同步代码
protected static TransactionLog tranLog;
public static synchronized void process() {
Random r = new Random();
tranLog = new TransactionLog();
String rid = r.nextInt(40000)+"";
tranLog.setTxnid(rid);
}
Making static synchronized
will allow only one thread at any given time.
进行静态同步将在任何给定时间仅允许一个线程。
#2
1
Class name TransactionLog implies that evety instance of TransactionLog, writed to variable tranLog will be used only in one thread.
类名TransactionLog意味着TransactionLog的evety实例,写入变量tranLog只能在一个线程中使用。
If it right, then read further:
如果是的话,那就进一步阅读:
In very good book "Java Concurrency in Practice" described one good pattern of thread synchronization:
在非常好的书“Java Concurrency in Practice”中描述了一种良好的线程同步模式:
Thread Confinement
Accessing shared, mutable data requires using synchronization; one way to avoid this requirement is to not share. If data is only accessed from a single thread, no synchronization is needed. This technique, thread confinement, is one of the simplest ways to achieve thread safety. When an object is confined to a thread, such usage is automatically thread-safe even if the confined object itself is not [CPJ 2.3.2].
访问共享的可变数据需要使用同步;避免这种要求的一种方法是不分享。如果仅从单个线程访问数据,则不需要同步。这种技术,线程限制,是实现线程安全的最简单方法之一。当一个对象局限于一个线程时,即使受限对象本身不是[CPJ 2.3.2],这种用法也是自动线程安全的。
Make field tranLog just local variable
使字段tranLog只是局部变量
final TransactionLog tranLog = new TransactionLog();
If you use it in other function, for instance subProcess2:
如果您在其他函数中使用它,例如subProcess2:
private void subProcess2() {
tranLog.doSometthing();
}
Add tranLog to function parameters:
将tranLog添加到函数参数:
private void subProcess2(TransactionLog tranLog) {
tranLog.doSometthing();
}
And pass tranLog when calling subProcess2.
并在调用subProcess2时传递tranLog。