Создание многопоточных приложений, который создает несколько потоков и запросов же таблицы базы данныхjava.lang.NullPointerException при выполнении многопоточных приложений баз данных
Учитывая XML входной файл с форматом:
<transliteration>
<element>
<source>about us</source>
</element>
</transliteration>
Применение читает несколько файлов и создает несколько потоков по одному для каждого файла XML и вывод будет другой XML-файл с форматом
<transliteration>
<element>
<source>about us</source>
<target/>
</element>
</transliteration>
ниже Прави п метод резьбы
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 ** функция принимает имя файла в качестве входа и загружает контент XML в документе.
getCompleteStringTransliterate ** является функцией MulltipleDatabaseThread класса, который возвращает переменную карту, которая содержит источник и его traget строку в нем.
getRecordsFromDatabase ** является anoher функции в том же классе, который разбивает исходную строку и получает свою целевую строку снова возвращает Map переменной
общественного класс 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; } }
}
обе эти функции используют переменную static/shared map в OutputReco класс-й и создает несколько потоков, которые на самом деле дает вызов базы данных и заселяет общую переменную карту и вернуть эту переменную
, но на выполнение этой программы ее давая
Exception in thread "Thread-0" java.lang.NullPointerException
at transliterationthreading.ExecuteOuterThread.run(ExecuteOuterThread.java:66)
на линии
if(map.get(sourceString) == null || map.get(sourceString).equals("") || map.get(sourceString).equals(sourceString))
Так один поток заканчивается, а затем выполняется полностью и полностью генерируется выходной файл. Я не понимаю, может ли кто-нибудь предложить какое-либо предложение в решении этой проблемы.
Благодаря
Я подозреваю, что 'map' будет пустым, когда этот поток запущен. 'map = OutputRecords.getRecords();' cuasing это будет NULL? – sanbhat
OutputRecords.getRecords(); return static map variable, которая инициализируется при загрузке класса, может быть пустым, но я не знаю, когда я мог бы быть нулевым. –
Вы пытались объявить переменную карты неустойчивой? – Jk1