Creating a multi-threaded application which creates multiple threads and queries same table of the database
Given the input xml file with format:
<transliteration>
<element>
<source>about us</source>
</element>
</transliteration>
Application reads multiple files and creates multiple threads one for each xml file and output will be another xml file with format
<transliteration>
<element>
<source>about us</source>
<target/>
</element>
</transliteration>
below is the run method of the thread
public void run() {
MultipleDatabaseThread th = new MultipleDatabaseThread();
Map<String,String> map = new HashMap<String,String>();
try
{
Document doc = loadXmlContentToMemory(this.inputString);
XPathExpression expr = null;
XPathFactory xFactory = XPathFactory.newInstance();
XPath xPath = xFactory.newXPath();
expr = xPath.compile("/transliteration/element//source");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
String sourceString = "";
if(nodes.getLength() > 0)
{
for (int i=0; i<nodes.getLength();i++)
{
//System.out.println("Name: "+nodes.item(i).getNodeName() +" Local Name: "+nodes.item(i).getLocalName() +" Value: "+nodes.item(i).getTextContent());
sourceString = nodes.item(i).getTextContent();
map = th.getCompleteStringTransliterate(sourceString, this.language);
if(map.get(sourceString) == null || map.get(sourceString).equals("") || map.get(sourceString).equals(sourceString))
{
map.clear();
map = th.getRecordsFromDatabase(sourceString, language);
Element abc = doc.createElement("target");
String targetString = "";
String[] tokens = sourceString.trim().split("\\s+");
for(int itr=0; itr < tokens.length; itr++)
{
targetString = targetString+" "+map.get(tokens[itr]);
}
abc.setTextContent(targetString.trim());
nodes.item(i).getParentNode().appendChild(abc);
}
else
{
Element abc = doc.createElement("target");
abc.setTextContent(map.get(sourceString));
nodes.item(i).getParentNode().appendChild(abc);
}
}
}
try
{
expr = xPath.compile("/transliteration/element//target");
result = expr.evaluate(doc, XPathConstants.NODESET);
}catch(XPathExpressionException ex)
{ }
NodeList nodesList = (NodeList) result;
for(int i =0;i<nodesList.getLength();i++)
{
System.out.println("Node Name: "+nodesList.item(i).getNodeName()+" Node Value: "+nodesList.item(i).getTextContent());
}
try
{
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StreamResult strResult = new StreamResult(new File(this.inputString+"_out.xml"));
if(doc != null && strResult != null)
{
DOMSource source = new DOMSource(doc);
transformer.transform(source, strResult);
}
}
catch(TransformerException ex)
{
System.out.println(""+ex);
}
catch(TransformerFactoryConfigurationError ex)
{
System.out.println(""+ex);
}
}catch(IOException ex)
{
ex.printStackTrace(System.out);
}
catch(DOMException ex)
{
ex.printStackTrace(System.out);
}
catch(ParserConfigurationException ex)
{
ex.printStackTrace(System.out);
}
catch(SAXException ex)
{
ex.printStackTrace(System.out);
}
catch(XPathExpressionException ex)
{
ex.printStackTrace(System.out);
}
catch(InterruptedException ex)
{
ex.printStackTrace(System.out);
}
}
loadXmlContentToMemory** function takes filename as a input and loads xml content in the Document.
getCompleteStringTransliterate** is a function of MulltipleDatabaseThread class which returns a map variable which contain source and its traget string in it.
getRecordsFromDatabase** is anoher function in same class which splits source string and gets its target string again returns map variable
public class MultipleDatabaseThread {
public Map<String,String> getCompleteStringTranslate(String inputString, String language) throws InterruptedException { Map<String,String> map = new HashMap<String,String>(); synchronized(OutputRecords.getMap()) { //long startTime = System.currentTimeMillis(); OutputRecords.clearOutputStream(); Thread thCompleteString = new DatabaseThread(inputString, language); thCompleteString.start(); thCompleteString.join(); map = OutputRecords.getRecords(); //System.out.println("Complete String Time Taken:: "+(System.currentTimeMillis()-startTime)); return map; } } public Map<String,String> getRecordsFromDatabase(String inputString, String language) throws InterruptedException { String[] tokens = inputString.split("\\s+"); Map<String,String> map = new HashMap<String,String>(); Thread[] databaseThreads = new Thread[tokens.length]; synchronized(OutputRecords.getMap()) { //long startTime = System.currentTimeMillis(); OutputRecords.clearOutputStream(); for(int index=0; index < tokens.length; index++) { databaseThreads[index] = new DatabaseThread(tokens[index],language); databaseThreads[index].start(); } for(int index = 0 ; index < tokens.length; index++) { databaseThreads[index].join(); } map = OutputRecords.getRecords(); //System.out.println("Tokens Time Taken:: "+(System.currentTimeMillis()-startTime)); return map; } }}
both these functions uses a static/shared map variable in OutputRecord class and generates multiple threads which actually gives call to database and populates shared map variable and return that variable
but on execution of this program its giving
Exception in thread "Thread-0" java.lang.NullPointerException
at transliterationthreading.ExecuteOuterThread.run(ExecuteOuterThread.java:66)
on line
if(map.get(sourceString) == null || map.get(sourceString).equals("") || map.get(sourceString).equals(sourceString))
So one thread gets terminated and then other gets executed completely and generates output file. I am not getting the problem can anyone gve some suggestion in solving this problem.
Thanks
mapto be null when that thread is running.map = OutputRecords.getRecords();cuasing it to be NULL?