2015-11-01 117 views
1

我需要從rss提要每5分鐘更新一次新聞提要。在這種情況下,我是否需要每次創建DocumentBuilderFactory?

爲此,我寫了一個TimerTask如下圖所示

public class TimerTaskForAllNews 
{ 
    public static void main(String[] args) 
    { 
     TimerTask task = new AllNewsUpdatrUtility(); 
     Timer timer = new Timer(); 
     timer.schedule(task, 1000,60000); 
    } 
} 

這是我的TimerTask實現類

package com.util; 
import java.net.URL; 
public class AllNewsUpdatrUtility extends TimerTask { 
     private static AllNewsUpdatrUtility instance = null; 
     public AllNewsUpdatrUtility() {} 
     public static AllNewsUpdatrUtility getInstance() { 
      if (instance == null) 
      instance = new AllNewsUpdatrUtility(); 
      return instance; 
     } 
    @Override 
    public void run() { 
     try { 
      JSONArray latestnews = new JSONArray(); 
      JSONObject jsonobj_allnews = new JSONObject(); 
      DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
      URL url = new URL("http://www.rssmix.com/u/8160628/rss.xml"); 
      Document doc = builder.parse(url.openStream()); 
      NodeList items = doc.getElementsByTagName("item"); 
      for (int i = 0; i < items.getLength(); i++) { 
       Element item = (Element) items.item(i); 
       String title = getValue(item, "title"); 
       String link = getValue(item, "link"); 
       String pub_date = getValue(item, "pubDate"); 

      } // for loop ends here 

      } catch (Exception e) { 
      e.printStackTrace(); 
      } 
    } 


} 

能否請你讓我知道,我反正可以改進這個方案?

+0

DBF IST不是線程安全的。如果你可以保證它只被一個線程使用,你可以緩存它。 – qqilihq

+1

但newDocumentBuilder()應該是線程安全的:https://jaxp.java.net/docs/spec/html/#plugabililty-thread-safety。因此,可以一勞永逸地創建一個DBF,並從多個線程中重用它來創建文檔構建器。 –

+0

那又如何? newDocumentBuilder()不是一個setter方法。它不配置工廠。因此,您可以創建一個工廠並從** one **線程配置它,然後發佈它,以便任何線程可以同時調用其newDocumentBuilder()方法,因爲newDocumentBuilder()是線程安全的。 –

回答

1

規範JSR 206 Java™ API for XML Processing (JAXP) 1.4

預計一實施SAXParserFactory的的newSAXParser方法,一個的DocumentBuilderFactory的newDocumentBuilder方法和一個TransformerFactory的newTransformer方法是線程安全無副作用。

正如評論說,你可以緩存的DocumentBuilderFactory實例:

package com.util; 
import java.net.URL; 
public class AllNewsUpdatrUtility extends TimerTask { 
     private static AllNewsUpdatrUtility instance; 
     private final DocumentBuilderFactory dbf; 
     private AllNewsUpdatrUtility() {} 
     public synchronized static AllNewsUpdatrUtility getInstance() { 
      if (instance == null) 
      instance = new AllNewsUpdatrUtility(); 
      dbf = DocumentBuilderFactory.newInstance(); 
      return instance; 
     } 
    @Override 
    public void run() { 
     try { 
      JSONArray latestnews = new JSONArray(); 
      JSONObject jsonobj_allnews = new JSONObject(); 
      DocumentBuilder builder = dbf.newDocumentBuilder(); 
      URL url = new URL("http://www.rssmix.com/u/8160628/rss.xml"); 
      Document doc = builder.parse(url.openStream()); 
      NodeList items = doc.getElementsByTagName("item"); 
      for (int i = 0; i < items.getLength(); i++) { 
       Element item = (Element) items.item(i); 
       String title = getValue(item, "title"); 
       String link = getValue(item, "link"); 
       String pub_date = getValue(item, "pubDate"); 

      } // for loop ends here 

      } catch (Exception e) { 
      e.printStackTrace(); 
      } 
    } 


} 
+0

這遠不是線程安全的:構造函數應該是私有的,dbf不應該是靜態的:它應該是最終的並在構造函數中初始化,並且應該同步getInstance()方法。 –

+0

@JBNizet OP沒有要求一個線程安全的類,但你是完全正確的。我已經包含了你的建議。 –

相關問題