如何并行化这个groovy代码?

时间:2010-05-26 16:57:34

标签: concurrency groovy

我正在尝试在Groovy中编写一个可重用的组件,以便轻松地从我们的一些Java应用程序中发送电子邮件。我想传递一个List,其中Email只是一个POJO(POGO?),带有一些电子邮件信息。我希望它是多线程的,至少在第二个线程中运行所有电子邮件逻辑,或者为每个电子邮件创建一个线程。

我对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
}

2 个答案:

答案 0 :(得分:12)

为了让您举例说明上述并行运行,您必须更换行

threads.each { it.run() }

threads.each { it.start() }

因为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)
    }
  }

}

答案 1 :(得分:2)

几个Java版本(1.5)他们引入了一些新的并发内容,使Java线程(甚至更多)变得简单。谷歌的java ThreadExecutor,你会发现一些页面,如:

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

Groovy是否使它更简单,我不能说,但您可能希望在进行比较之前首先将“新”Java技术应用于Java示例。