2010-05-26 55 views
3

我正在嘗試在Groovy中編寫可重用組件,以輕鬆地從我們的某些Java應用程序中發送電子郵件。我想通過它列表,其中電子郵件只是一個POJO(POGO?)與一些電子郵件信息。我希望它是多線程的,至少在第二個線程中運行所有的電子郵件邏輯,或者爲每個電子郵件創建一個線程。如何並行化這個groovy代碼?

我對Java中的多線程非常模糊,所以可能沒有幫助!我已經嘗試了幾種不同的方式,但這裏是我現在所擁有的:

void sendEmails(List<Email> emails) { 

    def threads = [] 

    def sendEm = emails.each{ email -> 
     def th = new Thread({ 
      Random rand = new Random() 
      def wait = (long)(rand.nextDouble() * 1000) 
      println "in closure" 
      this.sleep wait 
      sendEmail(email) 
     }) 
     println "putting thread in list" 
     threads << th 
    } 

    threads.each { it.run() } 
    threads.each { it.join() } 

} 

我希望睡眠會隨機慢一些線程下來,控制檯輸出將不會是連續的。相反,我看到:

putting thread in list 
putting thread in list 
putting thread in list 
putting thread in list 
putting thread in list 
putting thread in list 
putting thread in list 
putting thread in list 
putting thread in list 
putting thread in list 
in closure 
sending email1 
in closure 
sending email2 
in closure 
sending email3 
in closure 
sending email4 
in closure 
sending email5 
in closure 
sending email6 
in closure 
sending email7 
in closure 
sending email8 
in closure 
sending email9 
in closure 
sending email10 

sendEmail基本上沒有你所期望的東西,包括println語句,以及調用此遵循客戶端,

void doSomething() { 

    Mailman emailer = MailmanFactory.getExchangeEmailer() 

    def to = ["one","two"] 
    def from = "noreply" 

    def li = [] 
    def email 
    (1..10).each { 
     email = new Email(to,null,from,"email"+it,"hello") 
     li << email 
    } 

    emailer.sendEmails li 
} 

回答

10

要得到上面同時運行例如你你有

threads.each { it.start() } 

更換線

threads.each { it.run() } 

run()不會啓動一個新的線程,因此您的代碼依次運行。

還有一個名爲GPars的Groovy擴展。它支持多種併發技術,如Fork/Join或Actor模型。使用GPars,你的代碼可以簡化爲:

def sendEmails(emails) { 

    GParsPool.withPool { 
    emails.eachParallel { email -> 
     def wait = (long) new Random().nextDouble() * 1000 
     println "in closure" 
     this.sleep wait 
     sendEmail(email) 
    } 
    } 

} 
2

一對夫婦的Java版本背部(1.5 )他們引入了一些新的併發性的東西,使Java線程(甚至更多)變得簡單。谷歌對Java ThreadExecutor,你會發現一些頁面,例如:

http://www.deitel.com/articles/java_tutorials/20051126/JavaMultithreading_Tutorial_Part4.html

無論Groovy中使得它更簡單,我不能說,但你可能想申請「新」的Java技術,將您Java示例首先進行比較。

+0

謝謝唐,這有幫助。我替換了運行並使用threadExecutor.execute加入,然後是threadExecutor.shutdown(),最後是threadExecutor.awaitTermination(1,TimeUnit.MINUTES),因爲我認爲它過早地退出並殺死了衍生的線程。看起來我現在已關閉並正在運行。 – lucas 2010-05-26 17:34:00

+0

酷!很高興這有幫助。 – 2010-05-26 19:33:33