Skip to content

Commit f543057

Browse files
feat: Implement Actor Model pattern iluwatar#3232
1 parent 9de12ea commit f543057

File tree

9 files changed

+354
-0
lines changed

9 files changed

+354
-0
lines changed

Diff for: actor-model/README.md

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Actor Model
2+
3+
## Intent
4+
5+
The Actor Model is a concurrency pattern that treats "actors" as the fundamental units of computation. Each actor has its own state and behavior and interacts with other actors exclusively through message passing.
6+
7+
## Explanation
8+
9+
### Real-world Example
10+
11+
Imagine a team of people (actors) working in an office. They don’t share the same brain (memory), but instead communicate by passing notes (messages). Each person reads one note at a time and responds accordingly.
12+
13+
### Problem
14+
15+
Managing concurrent behavior in a safe and scalable way is difficult, especially with shared memory and race conditions.
16+
17+
### Solution
18+
19+
Encapsulate state and behavior within individual actors that communicate through asynchronous messages.
20+
21+
## Class Diagram
22+
23+
![UML Diagram](etc/actor-model.png)
24+
25+
## Participants
26+
27+
- **Actor**: Base class that defines a mailbox and handles incoming messages sequentially.
28+
- **Message**: Represents communication between actors.
29+
- **ActorSystem**: Creates and manages actors.
30+
- **PrinterActor**: Sample actor that prints incoming messages.
31+
32+
## Applicability
33+
34+
Use the Actor Model pattern when:
35+
36+
- You need a simple and safe way to handle concurrency.
37+
- You want to avoid thread synchronization issues like race conditions and deadlocks.
38+
- You want each object to process messages independently.
39+
40+
## Example
41+
42+
```java
43+
ActorSystem system = new ActorSystem();
44+
Actor printer = system.actorOf(new PrinterActor());
45+
46+
printer.send(new Message("Hello Actor!", null));
47+
printer.send(new Message("Another message", null));
48+
49+
Thread.sleep(1000);
50+
51+
((PrinterActor) printer).stop();
52+
system.shutdown();

Diff for: actor-model/etc/actor-model.urm.puml

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@startuml actor-model
2+
3+
title Actor Model - UML Class Diagram
4+
5+
class ActorSystem {
6+
+actorOf(actor: Actor): Actor
7+
+shutdown(): void
8+
}
9+
10+
class Actor {
11+
-mailbox: BlockingQueue<Message>
12+
-active: boolean
13+
+send(message: Message): void
14+
+stop(): void
15+
+run(): void
16+
#onReceive(message: Message): void
17+
}
18+
19+
class ExampleActor {
20+
+onReceive(message: Message): void
21+
}
22+
23+
class Message {
24+
-content: String
25+
-sender: Actor
26+
+getContent(): String
27+
+getSender(): Actor
28+
}
29+
30+
ActorSystem --> Actor : creates
31+
Actor <|-- ExampleActor : extends
32+
Actor --> Message : processes
33+
ExampleActor --> Message : uses
34+
35+
@enduml
46.2 KB
Loading

Diff for: actor-model/pom.xml

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
5+
6+
The MIT License
7+
Copyright © 2014-2022 Ilkka Seppälä
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
-->
28+
<project xmlns="http://maven.apache.org/POM/4.0.0"
29+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
30+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
31+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
32+
33+
<modelVersion>4.0.0</modelVersion>
34+
35+
<parent>
36+
<groupId>com.iluwatar</groupId>
37+
<artifactId>java-design-patterns</artifactId>
38+
<version>1.26.0-SNAPSHOT</version>
39+
</parent>
40+
41+
<artifactId>actor-model</artifactId>
42+
<name>Actor Model</name>
43+
44+
<dependencies>
45+
<!-- Add any dependencies you need (optional) -->
46+
</dependencies>
47+
48+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.actormodel;
26+
27+
import java.util.concurrent.BlockingQueue;
28+
import java.util.concurrent.LinkedBlockingQueue;
29+
30+
public abstract class Actor implements Runnable {
31+
private final BlockingQueue<Message> mailbox = new LinkedBlockingQueue<>();
32+
private volatile boolean active =
33+
true; // always read from main memory and written back to main memory,
34+
35+
// rather than being cached in a thread's local memory. To make it consistent to all Actors
36+
37+
public void send(Message message) {
38+
mailbox.add(message); // Add message to queue
39+
}
40+
41+
public void stop() {
42+
active = false; // Stop the actor loop
43+
}
44+
45+
@Override
46+
public void run() {
47+
while (active) {
48+
try {
49+
Message message = mailbox.take(); // Wait for a message
50+
onReceive(message); // Process it
51+
} catch (InterruptedException e) {
52+
Thread.currentThread().interrupt();
53+
}
54+
}
55+
}
56+
57+
// Child classes must define what to do with a message
58+
protected abstract void onReceive(Message message);
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.actormodel;
26+
27+
import java.util.concurrent.ExecutorService;
28+
import java.util.concurrent.Executors;
29+
30+
public class ActorSystem {
31+
private final ExecutorService executor = Executors.newCachedThreadPool();
32+
33+
public Actor actorOf(Actor actor) {
34+
executor.submit(actor); // Run the actor in a thread
35+
return actor;
36+
}
37+
38+
public void shutdown() {
39+
executor.shutdownNow(); // Stop all threads
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.actormodel;
26+
27+
public class App {
28+
public static void main(String[] args) throws InterruptedException {
29+
ActorSystem system = new ActorSystem();
30+
Actor Srijan = system.actorOf(new ExampleActor());
31+
32+
/* Actor Srijan = new ExampleActor() ;
33+
system.actorOf(Srijan); this is also acceptable
34+
*/
35+
36+
Srijan.send(new Message("Hello Actor!", Srijan));
37+
Srijan.send(new Message("Another message", Srijan));
38+
39+
Thread.sleep(1000); // Give time for messages to process
40+
41+
Srijan.stop(); // Stop the actor gracefully
42+
system.shutdown(); // Stop the actor system
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.actormodel;
26+
27+
public class ExampleActor extends Actor {
28+
@Override
29+
protected void onReceive(Message message) {
30+
System.out.println("Received :" + message.getContent());
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.actormodel;
26+
27+
public class Message {
28+
private final String content;
29+
private final Actor sender;
30+
31+
public Message(String content, Actor sender) {
32+
this.content = content;
33+
this.sender = sender;
34+
}
35+
36+
public String getContent() {
37+
return content;
38+
}
39+
40+
public Actor getSender() {
41+
return sender;
42+
}
43+
}

0 commit comments

Comments
 (0)