Groovy Concurrency Models
GPars
GPars 是面向Groovy/Java并行计算的开源库。
Parallel(并行方法)
GPar提供了类似于Category的机制,可以动态的为Collection添加parrel方法(并行计算)。
例如:
@Grab(group='org.codehaus.gpars', module='gpars', version='1.2.1')
import groovyx.gpars.GParsPool
class Student { int graduationYear; double gpa; }
// create a list of students
Collection<Student> students = [new Student(graduationYear: 2020, gpa:100.0), new Student(graduationYear: 2020, gpa:200.0)]
GParsPool.withPool {
def bestGpa = students.parallel.
filter{ s -> s.graduationYear == 2020}.
map{ s -> s.gpa }.
max()
println "Bset GPA: ${bestGpa}"
执行结果如下:
Bset GPA: 200.0
Actors
Actor是并行计算的一个模式。
- 并行计算中各个Actor在各自的线程运行。
- act:各自的计算逻辑
- loop:消息循环
- terminate: 退出消息循环
- act:各自的计算逻辑
- 状态(数据)在各自的线程中管理
- afterStart: 可对状态进行初始化。
- 通过GPar来交换数据
- send: 发送消息
- react: 接受消息
@Grab("org.codehaus.gpars:gpars:1.2.1")
import groovyx.gpars.actor.Actor
import groovyx.gpars.actor.DefaultActor
class Dragon extends DefaultActor {
int age
void afterStart() {
age = new Random().nextInt(1000) + 1
}
void act() {
loop {
react { int num ->
if (num > age)
reply 'too old'
else if (num < age)
reply 'too young'
else {
reply 'you guessed right!'
terminate()
}
}
}
}
}
// Guesses the age of the Dragon
class Guesser extends DefaultActor {
String name
Actor server
int myNum
void act() {
loop {
myNum = new Random().nextInt(1000) + 1
server.send myNum
react {
switch (it) {
case 'too old': println "$name: $myNum was too old"; break
case 'too young': println "$name: $myNum was too young"; break
default: println "$name: I won $myNum"; terminate(); break
}
}
}
}
}
def master = new Dragon().start()
def player = new Guesser(name: 'Guesser', server: master).start()
//this forces main thread to live until both actors stop
[master, player]*.join()