Preface
I have only written a couple of multithreaded programs in my day. It's usually once every two years when I have to do this. I'm trying to get more educated on the subject and I'm reading "Java Concurrency in Practice." I have a basic understanding.
Overview:
Typically, I never share objects across threads because it's easier and in most cases I'm just trying to avoid basic blocking scenarios. However, I have a use case where it makes sense to share an object across threads.
My JSONBmBindMappingRow is instantiated in my main thread (different class not included here). A private object BMBindMappingRow is set in JSONBmBindMappingRow . You can think of the JSONBmBindMappingRow class as immutable; although, it's definitely not. However, I will be treating it that way in my program.
After the JSONBmBindMappingRow is instantiated it can be assigned to multiple threads which will call getJsonRow().
Question:
The scope of my question is as follows: If two or more threads access the getJsonRow() at the sametime is this thread-safe since both will have a copy of the JSONBmBindMappingRow in there own memory cache? I think it's safe and synchronization is not needed, but I will leave it to the experts.
Is this code thread safe if two threads access it at the same time?
public JSONRow getJsonRow()
{
JSONRow jrow = new JSONRow();
for (Integer index: bbmr.getColumnMappingAll().keySet()) {
BMFieldMapping bm = bbmr.getColumnMapping(index);
if (bm.ws_field_name != null && !bm.ws_field_name.equalsIgnoreCase("")) {
jrow.add(new JSONField(bm.ws_field_name, bm.getJavaDataType(), 1));
}
}
return jrow;
}
JSONBmBindMappingRow Class:
package xxfi.oracle.apps.ws.json.row;
import java.sql.Connection;
import java.sql.SQLException;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleResultSet;
import oracle.jdbc.OracleTypes;
import xxfi.oracle.apps.ws.bm.BMBindMappingRow;
import xxfi.oracle.apps.ws.bm.BMFieldMapping;
import xxfi.oracle.apps.ws.utility.JDBC;
public class JSONBmBindMappingRow implements JSONRowBuildImpl
{
private BMBindMappingRow bbmr = new BMBindMappingRow();
private Connection conn = null;
private String tableName = null;
private String className = this.getClass().getCanonicalName() ;
public JSONBmBindMappingRow(Connection conn, String tableName)
{
this.tableName = tableName;
this.conn = conn;
init();
}
public void init()
{
setColumnBindMappings();
}
public void setColumnBindMappings()
{
StringBuffer plSql = new StringBuffer();
plSql.append("DECLARE ");
plSql.append("BEGIN ");
plSql.append(" :1 := xxfi_bm_custom_table_api.get_column_binds ( ");
plSql.append(" :2 /*tablename*/");
plSql.append(");");
plSql.append("END;");
OracleCallableStatement oracleCallableStatement = null;
OracleResultSet oracleResultSet = null;
try {
oracleCallableStatement = (OracleCallableStatement) this.conn.prepareCall(plSql.toString());
oracleCallableStatement.registerOutParameter(1, OracleTypes.CURSOR);
JDBC.nullSafe(oracleCallableStatement, 2, tableName, OracleTypes.VARCHAR);
oracleCallableStatement.execute();
// get cursor and cast it to ResultSet
oracleResultSet = (OracleResultSet) oracleCallableStatement.getCursor(1);
// loop it like normal
while (oracleResultSet.next()) {
bbmr.add(new BMFieldMapping(oracleResultSet.getString("ws_field_name"),
oracleResultSet.getString("column_name"), oracleResultSet.getString("data_type"),
oracleResultSet.getInt("bind_number")));
}
} catch (Exception e) {
try {
this.conn.rollback();
} catch (SQLException f) {
// TODO
}
System.out.println("Error in "+className+".setColumnBindMappings(): " + e);
e.printStackTrace();
} finally {
JDBC.close(oracleCallableStatement, oracleResultSet);
}
}
public String getArrayName()
{
return "";
}
public JSONRow getJsonRow()
{
JSONRow jrow = new JSONRow();
for (Integer index: bbmr.getColumnMappingAll().keySet()) {
BMFieldMapping bm = bbmr.getColumnMapping(index);
if (bm.ws_field_name != null && !bm.ws_field_name.equalsIgnoreCase("")) {
jrow.add(new JSONField(bm.ws_field_name, bm.getJavaDataType(), 1));
}
}
return jrow;
}
public BMBindMappingRow getBbmr()
{
return bbmr;
}
}