春天花会开 2016-11-01
Groovy 多线程
Java 支持多线程。定义了 Runnable 接口,并在根类 Object 中提供了 wait/notify 方法,还有 synchronized 关键字的支持。我们常说实现多线程的方式有两种:继承 Thread类 和实现 Runnable接口,实质上工作者线程执行的都是 Runnable 接口中定义的 run() 方法,Thread 本身实现了 Runnable 接口,它不过是为线程的调度使用提供了许多有用的方法而已。
Groovy 在多线程方面自然也不会甘拜下风。Groovy 通过 MetaClass 对java.lang.Thread 进行了扩展,即所谓的 GDK - Groovy methods added to Java SE classes。
在原 java.lang.Thread 类中增加了两个方法,分别是:
static Thread start(Closure closure); static Thread startDaemon(Closure closure); //对应的是 Daemon 线程
这两个方法接受的参数是闭包,要知道所有的闭包都是继承自 groovy.lang.Closure,而它是实现了java.lang.Thread 的。所以使用闭包很容易实现 Groovy 中的多线程。
具体到代码上就有以下几种写法:
t = new Thread() {/* Closure body */}; t.start(); Thread.start { /* Closure body */}; Thread.startDaemon { /* Closure body */};
这样,闭包中的代码就会在一个新的线程中执行。真的是这样吗?最能加深印象的做法是我们用一段代码来测试一下,可以从两方面来观察,满足一项即可:
1. 闭包外部和内总分别打印出当前的线程名看是否不一样,是则为不同线程
2. 看闭包中的操作是否要阻塞主线程,不会则表示在新线程中执行的闭包
println "Outter thread: " + Thread.currentThread().getName() Thread.start { println "Inner thread: "+Thread.currentThread().getName() "How are you?".each { print it } } println "Fine, thank you."
执行后的输出都是:
Outter thread: main
Fine, thank you.
Inner thread: Thread-1
How are you?
线程名不一样,并且最后一行代码有机会在闭包执行之前或之中执行,从这两者中任一条件说明了闭包是在新线程中执行的。试着以通常的方式调用闭包,就是不一样的情况了。
Java 中可以使用 Timer 和 TimerTask 来实现定时任务--在新线程中执行。Groovy 对此 java.util.Timer 也有相应的扩展,增加了 runafter(int delay,Closure closure) 方法。因此在 Groovy 中应用 Timer 也能实现多线程:
new Timer().runAfter(1000) { /* Closure body */}
其他与线程相关 wait/notify 和 synchronized 控制,在使用上与 Java 差不多的。