2013-06-08 3 views
3

Создание многопоточных приложений, который создает несколько потоков и запросов же таблицы базы данных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)) 

Так один поток заканчивается, а затем выполняется полностью и полностью генерируется выходной файл. Я не понимаю, может ли кто-нибудь предложить какое-либо предложение в решении этой проблемы.

Благодаря

+1

Я подозреваю, что 'map' будет пустым, когда этот поток запущен. 'map = OutputRecords.getRecords();' cuasing это будет NULL? – sanbhat

+0

OutputRecords.getRecords(); return static map variable, которая инициализируется при загрузке класса, может быть пустым, но я не знаю, когда я мог бы быть нулевым. –

+0

Вы пытались объявить переменную карты неустойчивой? – Jk1

ответ

0

Я woud подозреваю, что изменения содержания карты при оценке линии

if(map.get(sourceString) == null || map.get(sourceString).equals("") || map.get(sourceString).equals(sourceString)) 

Таким образом, ваши нулевые чеки удастся, но новое значение, которое вы получаете от карты может быть пустым. Карта не синхронизирована!

Изменить эту строку

String sourceStringValue = map.get(sourceString); 
if(sourceStringValue == null || sourceStringValue.equals("") || map.get(sourceString).equals(sourceString)) 
+0

Я тоже это пробовал, но это не помогло мне. Однако я решил проблему, удалив общий подход к карте и используя ExecutorService и Callable Interface и вернув значение каждого потока с помощью метода call(). Спасибо всем за ваши усилия –

0

Спасибо всем за ваши усилия

я попытался решить эту проблему, используя другой подход, не используя статическую общую карту и с помощью ExecutorService и Callable интерфейса подхода

вот мой код

try 
     { 
      doc = loadXmlContentToMemory(this.inputString); 
      expr = xPath.compile("/transliteration/element//source"); 
      result = expr.evaluate(doc, XPathConstants.NODESET); 

     }catch(ParserConfigurationException ex) 
     { 
      System.out.println("loadXmlError: "+ex.toString()); 
     } 
     catch(IOException ex) 
     { 
      System.out.println("loadXmlError: "+ex.toString()); 
     } 
     catch(SAXException ex) 
     { 
      System.out.println("loadXmlError: "+ex.toString()); 
     } 
     catch(XPathExpressionException ex) 
     { 
      System.out.println("loadXmlError: "+ex.toString()); 
     } 

     NodeList nodes = (NodeList) result; 
     String sourceString = ""; 

     if(nodes.getLength() >0) 
     { 
      Map<String,String> fileMap = new HashMap<String,String>(); 
      ExecutorService executor = Executors.newFixedThreadPool(NTHREADS); 

      for(int index =0; index <nodes.getLength(); index++) 
      { 
       sourceString = nodes.item(index).getTextContent(); 
       Callable<Map<String,String>> worker = new MultipleDatabaseCallable(sourceString,language); 
       Future<Map<String,String>> map = executor.submit(worker); 

       try 
       { 
        //System.out.println(""+Thread.currentThread().getName()+"SourceString:: "+sourceString+"Map: "+map.get().get(sourceString)); 
         fileMap.putAll(map.get()); 
       }catch(InterruptedException ex) 
       { 
        System.out.println("future read: "+ex.toString()); 
       } 
       catch(ExecutionException ex) 
       { 
        System.out.println("future read: "+ex.toString()); 
       } 
      } 

      executor.shutdown(); 
      // Wait until all threads are finish 
      while (!executor.isTerminated()) { 

      } 
      ExecutorService tokenExecutor = Executors.newFixedThreadPool(NTHREADS); 
      for(int i =0 ;i<nodes.getLength();i++) 
      { 
       sourceString = nodes.item(i).getTextContent(); 
       if(fileMap.get(sourceString) == null || fileMap.get(sourceString).equals("") || fileMap.get(sourceString).equals(sourceString)) 
       { 
        fileMap.remove(sourceString); 
        Callable<Map<String,String>> worker = new MultipleTokenCallable(sourceString,language); 
        Future<Map<String,String>> map = tokenExecutor.submit(worker); 

        try 
        { 
         fileMap.putAll(map.get()); 
        } 
        catch(InterruptedException ex) 
        { 
         System.out.println("Tokenized put Interupted exception: "+ex.toString()); 
        } 
        catch(ExecutionException ex) 
        { 
         System.out.println("Tokenized put Execution exception: "+ex.toString()); 
         ex.printStackTrace(System.out); 
        } 

        Element targetElement = doc.createElement("target"); 
        String targetString = ""; 

        String[] tokens = sourceString.trim().split("\\s+"); 

        for(int itr=0; itr < tokens.length; itr++) 
        { 
         targetString = targetString+" "+fileMap.get(tokens[itr]); 
        } 
        targetElement.setTextContent(targetString.trim()); 
        nodes.item(i).getParentNode().appendChild(targetElement); 
        //System.out.println(""+Thread.currentThread().getName()+" Target: "+targetString+" Source: "+sourceString); 
       } 
       else 
       { 
        Element abc = doc.createElement("target"); 
        abc.setTextContent(fileMap.get(sourceString)); 
        nodes.item(i).getParentNode().appendChild(abc); 
       } 
      } 

      tokenExecutor.shutdown(); 
      // Wait until all threads are finish 
      while (!tokenExecutor.isTerminated()) { 

      } 
      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); 
      } 

     } 

, поскольку с помощью этого потока создается множество потоков, и все потоки пытаются подключиться к базе данных одновременно, это может привести к слишком большому количеству ошибок соединений, если число одновременных потоков увеличивается. Поэтому вам необходимо поддерживать пул соединений, чтобы преодолеть эту проблему.

Смежные вопросы