Sup everyone!
I wrote this code for Tomcat appserver but I am told from an
associate that it has threading issues. The basic idea is to store a
read only data table for everyone to use. It takes some time for the
table to be created. I want to store the table in a singleton and
update it periodicly, basicaly when a user logs into the system. By
keeping 1 table allocated I don't have to worry about memmory usage
and if a user does need the latest updated table he can log off and
then back in to refresh the table(if nobody else has done so already).
If this sounds like a cludge maybe it is, but right now I question my
knowledge of threading. Functionality can change and maybe updating
the table is best in a worker thread that updates periodicaly on a
timed interval.
So here is the suspected threading issue:
I have a singleton, pretty basic class.
private constructor.
GetInstance
GetTable
SetTable
with a self and table class variable.
the table is created in a javabean that is accessed in the servlet.
A user accessing the table will
GetInstane().SetTable(javabean.createTable()) if
firstTimeAccessingTable == true else GetInstane().GetTable()
My associate says that the getters and setters are the problem. He
said that if thread1 does myTableRef = GetInstance().GetTable() and
uses the table while thread2 does
GetInstane().SetTable(javabean.createTable()) that thread1's
myTableRef will change once thread2 does the set.
So my sandBox test is not threaded but I think should be a good enough
example. In my test I tested a "dataType" even though I am not sure
one calls the String class a true dataType and a created class. My
result show that myTableRef will not change once the setTable happens
from another thread. Here is the Code.
public class Singleton {
static Singleton me = null;
private String testDataType = null;
private TestClass testClass = null;
private Singleton(){
}
public static Singleton getInstance(){
if(me==null){
me = new Singleton();
}
return me;
}
public String getDataType(){
return testDataType;
}
public void setDataType(String dataType){
this.testDataType = dataType;
}
public TestClass getTestClass(){
return testClass;
}
public void setTestClass(TestClass testClass){
this.testClass = testClass;
}
}
public class TestClass{
public int value = 0;
public TestClass(int value){
this.value = value;
}
public TestClass(){}
}
public class SandBox {
public static void main(String[] args) {
Singleton x = Singleton.getInstance();
String origDataType = "freaky1";
TestClass origTestClass = new TestClass (5);
x.setDataType(origDataType);
x.setTestClass(origTestClass);
String retrieved1DataType = x.getDataType();
TestClass retrieved1TestClass = x.getTestClass();
String newDataType = "freaky2";
TestClass newTestClass = new TestClass (10);
x.setDataType(newDataType);
x.setTestClass(newTestClass);
String retrieved2DataType = x.getDataType();
TestClass retrieved2TestClass = x.getTestClass();
System.out.println("woot!");
}
}
In Debug mode at the "woot" println I find that the object ID's for
retrieved1DataType and retrieved2DataType are different as well as the
TestClass counterpart.
This tells me my associate is wrong. But what do you think? Should I
test a multithreaded senerio? Do you think the setters and getters
are thread safe? Will a getters's reference be safe from another
threads setter?
Thanks a bunch!
Erik