problem with threads
Hi all,
I have an issue on the view part (JSP Page).
Steps that caused the issue on the site.
When two different users simultanesouly click from their client machines. We generate a list and update it the volatile list of the usersession form. We read this list on the jsp page and print them in a table on the page.
now the problem is due to simultaneous clicks on the client machines, the thread of once click is reading the data from the list that is taken from the other thread
Can some one help me regarding this.
Thanks in advance.
[583 byte] By [
dynodevila] at [2007-11-26 18:52:39]

# 1
Your list accessor method should be a synchronized method.
hiwaa at 2007-7-9 6:26:41 >

# 2
Thanks for your support.
Here is what i am actually trying to print on the Console from the jsp page.
<%
String selectedtab = userSession.getDashboardTab();
FileStatisticsList fileStatisticsList = userSession.getFileStatsList();
for(int i=0;i<fileStatisticsList.size();i++){
FileStatistics fileStatistics = fileStatisticsList.getFileStatisticsAt(i);
System.out.println("*****************"+fileStatistics.getFileID()+"*****************");
}
PageDirection pageDirection = userSession.getPageDirection();
%>
the iteration part is custom defined and is as follows: (placed in side a public class FileStatisticsList)
public FileStatistics getFileStatisticsAt(int index) {
return (FileStatistics) list.get(index);
}
So what is that we need to synchronize here?
# 3
FileStatisticsList fileStatisticsList = userSession.getFileStatsList();
synchronized(fileStatisticsList) { // sync
for(int i=0;i<fileStatisticsList.size();i++){
FileStatistics fileStatistics = fileStatisticsList.getFileStatisticsAt(i);
System.out.println("*****************"+fileStatistics.getFileID()+"*****************");
}
}
>
# 4
Thanks!But a doubt here.Why do we need to synch the local list variable referencing a usersession field. It will be independant to the thread..ryt? why then we need to synch it. (my doubt is why is the thread referenceing the data from the heap of another thread)
# 5
The variable is thread-local, but the data it refers to isn't.
ejpa at 2007-7-9 6:26:41 >

# 6
public class UserSessionForm extends ActionForm implements Serializable {
....................................
....................................
private volatile FileStatisticsList fileStatsList = null;
}
This is the signature of the fileStatisticsList in usersession form
So as i am going to create new sessionform for each user, the vairable will be visible to the user thread and not to the other threads!! Correct me if i am wrong
Volatile might be the cause, had the varible be singleton, but this is not
the case here ..ryt?
Anyhow, I tried removing the modifier volatile, but it didnt solve the problem.
Any thoughts?
# 7
So what does the userSession.getFileStatsList() method do? Return the value of 'fileStatsList ' to callers maybe? who might be in other threads?
ejpa at 2007-7-9 6:26:42 >

# 8
[2/6/07 5:20:27:289 CST] 250feeb8 SystemOutO 20792:-:ELECARMC:-:COMPLETED_WITH_ERRORS:-:ELECARMC.U.200702020000.gsf
[2/6/07 5:20:27:290 CST] 3416eb8 SystemOutO 20745:-:ELECARMC:-:COMPLETE:-:ELECARMC.U.200511011800.gsf
[2/6/07 5:20:27:290 CST] 250feeb8 SystemOutO 20791:-:ELECARMC:-:COMPLETED_WITH_ERRORS:-:ELECARMC.U.200702020000.gsf
[2/6/07 5:20:27:291 CST] 3416eb8 SystemOutO 20727:-:ELECARMC:-:COMPLETED_WITH_ERRORS:-:ELECARMC.U.200701310000.gsf
[2/6/07 5:20:27:291 CST] 250feeb8 SystemOutO 20766:-:ELECARMC:-:COMPLETE:-:ELECARMC.U.200511011800.gsf
[2/6/07 5:20:27:291 CST] 250feeb8 SystemOutO 20765:-:ELECARMF:-:CMPL_REPR_PART_WITH_ERR:-:ELECARMF.U.200511011810.gsf
[2/6/07 5:20:27:291 CST] 250feeb8 SystemOutO 20746:-:ELECARMF:-:THRESHOLD_EXCEEDED:-:ELECARMF.U.200511011810.gsf
[2/6/07 5:20:27:291 CST] 3416eb8 SystemOutO 20745:-:ELECARMC:-:COMPLETE:-:ELECARMC.U.200511011800.gsf
If you see the above logs. the last line starting with [2/6/07 5:20:27:291 CST] 3416eb8 should be the from thread - 250feeb8 .
As the thread 3416eb8 finished its turn of looping thru the list, it then took the details from the list of other thread.
the usersessionform.getfilestatslist just returns the list in the session form.
# 10
Does this happen with the code suggested in reply #3?
ejpa at 2007-7-9 6:26:42 >

# 11
I presume that u are doing following thing in ur code.
1. prepare List for given client.
2. update this List in the form bean.
3. Retrieve data from the list and display it on JSP.
I see following 2 problems in ur code : -
1. Ur code for preparing list is not synchronised. So ur list can get corrupted by some other thread.
2. U are passing this reference of List to the formbean, without making a deep clone.
I think understanding first problem is easy , so lets discuss second one :
When u are passing this reference of list without making a deep clone it's quite possible that when Thread 1 is executing STEP 3, Thread 2 may come and execute STEP 1.
So now we have a scenario where two thread are working on the same reference. So when Thread 1 is displaying data, it might display some data of Thread 2.
To solve this problem u can do following : -
synchronized
{
1. prepare List for given client.
2. Make a deep clone of this List ensuring that even composite objects are cloned, so that references of all the objects and composite objects in this CLONED List is DIFFERENT from the original list.
3. update this CLONED List in the form bean.
}
I think this should solve ur problem.
I think synchronising ur Retrieval like this is not going to help, because u encounter data corruption when there is "SET" happening and not when there is "GET"
FileStatisticsList fileStatisticsList = userSession.getFileStatsList();
synchronized(fileStatisticsList) { // sync
for(int i=0;i<fileStatisticsList.size();i++){
FileStatistics fileStatistics = fileStatisticsList.getFileStatisticsAt(i);
System.out.println("*****************"+fileStatistics.getFileID()+"*****************");
}
}
Message was edited by:
Amrish>
# 12
i use a mapper (which is static) to retrive the data from the data base.
After retrieveing the database. I tried logging the retrieved data. and they were correct till the control id fwded tothe jsp page.
As soon as i enter the jsp after the imports..i tried printing the list and tthis time the data is getting messed up. Again reiterating the list is ok with data in both the threads. But after retrieveing the data completely from its corresponding list a thread is taking the data from another thread that is slow by a fraction of second.
Example of the case
Thread1 and Thread2 below has objects 1 throughh 10 each
The out put is like
Thread1:obj1
Thread2:obj1
Thread1:obj2
Thread2:obj2
Thread1:obj3
Thread2:obj3
Thread1:obj4
Thread2:obj4
Thread1:obj5
Thread2:obj5
Thread1:obj6
Thread2:obj6
Thread1:obj7
Thread2:obj7
Thread1:obj8
Thread2:obj8
Thread1:obj9
Thread1:obj10
Thread1:obj9
Thread1:obj10
Thread2:1
Thread2:2
Thread2:obj1
if you see at the bottom, thread 1 finished llooping through the list and started taking the details from the thread 2.
Also thread 1 has taken the object that should have been taken by the thread 2 for that iteration of loop.
Please let me know if you need more info?
# 13
> Does this happen with the code suggested in reply #3?yes the synchronized block too has the issue.
# 14
can some one help me out?Thanks in advance!
# 15
It's starting to look like you're getting your user sessions mixed up.
ejpa at 2007-7-21 17:30:53 >

# 16
but my usersession form is in session scopeand the list objects that i retrieved from the two distinct forms are also different (as with hashcode). Is there any specific way to fix this with out further digging for root cause.(to work with a safer code)
# 17
As said before,this is happening because ur sessions are sharing same object ..So u could do following
1. Synchronise the process of retrieving and updating data in the user session object.
synchronise
{
list = null;// let this be local variable.
list = getDataFromDB();
session.setAttribute("data". list);
}
OR
ur session can get corrupted if u do Ctrl + N in the browser of ur present session.
This opens up new browser on the client side but same session context is used on the server side......
This could corrupt ur data on the server.
Check this out.