要以PDF格式阅读本主题,请点击这里。 |
演员
GPars 中的演员支持受到 Scala 中演员库的启发,但随后已经超越了它。
演员允许基于消息的并发模型,由独立的活动对象构建,这些对象交换消息且没有可变的共享状态。 演员可以帮助解决或避免死锁、活锁或饥饿等问题,这些问题是共享内存的典型问题。 Ruben Vermeersch 最近对演员背后的关键概念进行了很好的总结。
内部演员
演员可以共享一个相对较小的线程池。 这可以扩展到许多并发演员共享一个单一的池化线程。 它们避免了 JVM 的线程限制。
演员代码以块的形式处理,块之间由等待新事件(消息)的静默期隔开。 这可以通过延续自然地建模。
由于 JVM 不直接支持延续,因此必须在演员框架中模拟它们,这对演员代码的组织有轻微的影响。 但是,在大多数情况下,好处 outweighs 困难。
演员示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import groovyx.gpars.actor.Actor
import groovyx.gpars.actor.DefaultActor
class GameMaster extends DefaultActor {
int secretNum
void afterStart() {
secretNum = new Random().nextInt(10)
}
void act() {
loop {
react { int num ->
if (num > secretNum)
reply 'too large'
else if (num < secretNum)
reply 'too small'
else {
reply 'you win'
terminate()
}
}
}
}
}
class Player extends DefaultActor {
String name
Actor server
int myNum
void act() {
loop {
myNum = new Random().nextInt(10)
server.send myNum
react {
switch (it) {
case 'too large':
println "$name: $myNum was too large"
break
case 'too small':
println "$name: $myNum was too small"
break
case 'you win':
println "$name: I won $myNum"; terminate()
}
}
}
}
}
def master = new GameMaster().start()
def player = new Player(name: 'Player', server: master).start()
[master, player]*.join()
由Jordi Campos i Miralles,巴塞罗那大学,数学系,应用数学与分析系提供示例