2010-04-06 38 views
3

我是groovy/grails的新手。groovy多線程

如何爲此代碼實現線程。有2500個網址,這需要幾個小時的時間來檢查每個網址。

,所以我決定實現多線程此:

這裏是我的示例代碼:

def urls = [ 
    "http://www.wordpress.com", 
    "http://67.192.103.225/QRA.Public/" , 
    "http://www.subaru.com", 
    "http://baldwinfilter.com/products/start.html" 
] 

def up = urls.collect { ur -> 
    try { 
     def url = new URL(ur) 
     def connection = url.openConnection() 
     if (connection.responseCode == 200) { 
      return true 
     } else { 
      return false 
     } 
    } catch (Exception e) { 
     return false 
    } 
} 

對於這個代碼我需要實現多線程
任何人都可以向我推薦代碼。

在此先感謝,
sri。

回答

3

See the Groovy docs舉例說明如何使用ExecutorService來做你想做的事。

+0

感謝Aaron.I將讀取和測試。 – srinath 2010-04-06 10:29:04

11

我會看看Groovy Parallel Systems庫。特別是我認爲Parallel collections部分會很有用。

看着文檔,我相信collectParallel是一個直接替代collect(銘記關於副作用的明顯警告)。以下工作適合我:

def urls = [ 
    "http://www.wordpress.com", 
    "http://www.subaru.com", 
    "http://baldwinfilter.com/products/start.html" 
] 
Parallelizer.doParallel { 
    def up = urls.collectParallel { ur -> 
     try { 
      def url = new URL(ur) 
      def connection = url.openConnection() 
      if (connection.responseCode == 200) { 
       return true 
      } else { 
       return false 
      } 
     } catch (Exception e) { 
      return false 
     } 
    } 
    println up 
} 
+0

嗨mojones,請你給我提供一個類似於我的需要的小例子。我已經通過了文檔。 – srinath 2010-04-06 09:47:31

+0

我編輯了我的原始答案以包含示例,因爲我不認爲我可以在評論中使用代碼格式。 – mojones 2010-04-06 14:28:31

+0

另外需要注意的是:你可以傳遞一個參數給collectParallel給出要使用的線程數量;如果您遇到需要很長時間才能返回狀態代碼的服務器,您可能需要將其設置爲大數目。 – mojones 2010-04-06 14:33:27

1

您可以使用它來檢查單獨的線程中的URL。

class URLReader implements Runnable 
{ 
    def valid 
    def url 

    URLReader(url) { 
     this.url = url 
    } 

    void run() { 
     try { 
      def connection = url.toURL().openConnection() 
      valid = (connection.responseCode == 200) as Boolean 
     } catch (Exception e) { 
      println e.message 
      valid = Boolean.FALSE 
     } 
    } 
} 
def reader = new URLReader("http://www.google.com") 
new Thread(reader).start() 
while (reader.valid == null) 
{ 
    Thread.sleep(500) 
} 
println "valid: ${reader.valid}" 

注:有效屬性將爲null,Boolean.TRUE或Boolean.FALSE。您需要等待一段時間才能讓所有線程有機會打開連接。根據您檢查的URL數量,您最終會達到您可以切實處理的線索數量/連接數量的限制,因此應該按照適當大小的批量檢查URL。

+0

謝謝安德魯。我用你的解決方案嘗試了一些小修改。我創建了Groovy類,名稱爲ValidateLinks,它擴展了Thread。這是工作,但無法運行線程超過網站數400 +。請查看我發佈的新答案。 – srinath 2010-04-07 10:57:33

0

這是我如何實現:

class ValidateLinks extends Thread{ 
    def valid 
    def url 

    ValidateLinks(url) { 
     this.url = url 
    } 

    void run() { 
     try { 
      def connection = url.toURL().openConnection() 
     connection.setConnectTimeout(5000) 
      valid = (connection.responseCode == 200) as Boolean 
     } catch (Exception e) { 
      println url + "-" + e.message 
      valid = Boolean.FALSE 
     } 
    } 
} 

def threads = []; 
urls.each { ur -> 
def reader = new ValidateLinks(ur.site_url) 
reader.start() 
threads.add(reader); 
} 

while (threads.size() > 0) { 

     for(int i =0; i < threads.size();i++) { 
       def tr = threads.get(i); 
       if (!tr.isAlive()) { 
         println "URL : " + tr.url + "Valid " + tr.valid 
         threads.remove(i); 
         i--; 

       } 
     } 
} 
1

我覺得這種方式是實現非常簡單。


import java.util.concurrent.* 

//Thread number 
THREADS = 100 
pool = Executors.newFixedThreadPool(THREADS) 
defer = { c -> pool.submit(c as Callable) } 

def urls = [ 
    "http://www.wordpress.com", 
    "http://www.subaru.com", 
] 

def getUrl = { url -> 
    def connection = url.openConnection() 
    if (connection.responseCode == 200) { 
    return true 
    } else { 
    return false 
    } 
} 


def up = urls.collect { ur -> 
    try { 
     def url = new URL(ur) 
    defer{ getUrl(url) }.get() 
    } catch (Exception e) { 
     return false 
    } 
} 

println up 
pool.shutdown()