Skip to content

Commit 11abf48

Browse files
feat: update Actor Model implementation with multi-actor logic #3251
1 parent 3ee44ea commit 11abf48

File tree

6 files changed

+66
-21
lines changed

6 files changed

+66
-21
lines changed

Diff for: actor-model/src/main/java/com/iluwatar/actormodel/Actor.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@
2424
*/
2525
package com.iluwatar.actormodel;
2626

27+
import lombok.Getter;
28+
import lombok.Setter;
2729
import java.util.concurrent.BlockingQueue;
2830
import java.util.concurrent.LinkedBlockingQueue;
2931

3032
public abstract class Actor implements Runnable {
33+
34+
@Setter
35+
@Getter
36+
private String actorId;
3137
private final BlockingQueue<Message> mailbox = new LinkedBlockingQueue<>();
3238
private volatile boolean active =
3339
true; // always read from main memory and written back to main memory,
@@ -44,7 +50,7 @@ public void stop() {
4450

4551
@Override
4652
public void run() {
47-
while (active) {
53+
while ( active ) {
4854
try {
4955
Message message = mailbox.take(); // Wait for a message
5056
onReceive(message); // Process it

Diff for: actor-model/src/main/java/com/iluwatar/actormodel/ActorSystem.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,25 @@
2424
*/
2525
package com.iluwatar.actormodel;
2626

27+
import java.util.concurrent.ConcurrentHashMap;
2728
import java.util.concurrent.ExecutorService;
2829
import java.util.concurrent.Executors;
30+
import java.util.concurrent.atomic.AtomicInteger;
2931

3032
public class ActorSystem {
3133
private final ExecutorService executor = Executors.newCachedThreadPool();
34+
private final ConcurrentHashMap<String ,Actor > actorRegister = new ConcurrentHashMap<>();
35+
private final AtomicInteger idCounter = new AtomicInteger(0);
3236

33-
public Actor actorOf(Actor actor) {
37+
public void startActor(Actor actor) {
38+
String actorId = "actor-" + idCounter.incrementAndGet(); //Generate a new and unique ID
39+
actor.setActorId(actorId); // assign the actor it's ID
40+
actorRegister.put(actorId,actor); //Register and save the actor with it's ID
3441
executor.submit(actor); // Run the actor in a thread
35-
return actor;
42+
}
43+
44+
public Actor getActorById(String actorId){
45+
return actorRegister.get(actorId); // Find by Id
3646
}
3747

3848
public void shutdown() {

Diff for: actor-model/src/main/java/com/iluwatar/actormodel/App.java

+8-9
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,17 @@
2727
public class App {
2828
public static void main(String[] args) throws InterruptedException {
2929
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));
30+
Actor srijan = new ExampleActor(system);
31+
system.startActor(srijan);
32+
Actor ansh = new ExampleActor2(system);
33+
system.startActor(ansh);
34+
ansh.send(new Message("Hello Srijan" , srijan.getActorId()));
35+
srijan.send(new Message("Hello ansh!", srijan.getActorId()));
3836

3937
Thread.sleep(1000); // Give time for messages to process
4038

41-
Srijan.stop(); // Stop the actor gracefully
39+
srijan.stop(); // Stop the actor gracefully
40+
ansh.stop();
4241
system.shutdown(); // Stop the actor system
4342
}
4443
}

Diff for: actor-model/src/main/java/com/iluwatar/actormodel/ExampleActor.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,24 @@
2424
*/
2525
package com.iluwatar.actormodel;
2626

27+
import java.util.logging.Logger;
28+
2729
public class ExampleActor extends Actor {
30+
private final ActorSystem actorSystem;
31+
32+
public ExampleActor(ActorSystem actorSystem) {
33+
this.actorSystem = actorSystem;
34+
}
35+
Logger logger = Logger.getLogger(getClass().getName());
36+
2837
@Override
2938
protected void onReceive(Message message) {
30-
System.out.println("Received :" + message.getContent());
39+
logger.info("[" +getActorId()+ "]" + "Received : " + message.getContent());
40+
41+
Actor sender = actorSystem.getActorById(message.getSenderId());// sender actor id
42+
if(sender!=null && !message.getSenderId().equals(getActorId())) {
43+
sender.send(new Message("I got your message ", getActorId()));
44+
}
45+
3146
}
3247
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.iluwatar.actormodel;
2+
3+
import java.util.logging.Logger;
4+
5+
public class ExampleActor2 extends Actor{
6+
private final ActorSystem actorSystem;
7+
8+
public ExampleActor2(ActorSystem actorSystem) {
9+
this.actorSystem = actorSystem;
10+
}
11+
Logger logger = Logger.getLogger(getClass().getName());
12+
13+
@Override
14+
protected void onReceive(Message message) {
15+
logger.info("[" + getActorId()+"]" + "Received : " +message.getContent());
16+
}
17+
}

Diff for: actor-model/src/main/java/com/iluwatar/actormodel/Message.java

+6-8
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,16 @@
2626

2727
public class Message {
2828
private final String content;
29-
private final Actor sender;
29+
private final String senderId;
3030

31-
public Message(String content, Actor sender) {
31+
public Message(String content, String senderId) {
3232
this.content = content;
33-
this.sender = sender;
33+
this.senderId = senderId;
3434
}
3535

36-
public String getContent() {
37-
return content;
38-
}
36+
public String getContent() { return content; }
3937

40-
public Actor getSender() {
41-
return sender;
38+
public String getSenderId() {
39+
return senderId;
4240
}
4341
}

0 commit comments

Comments
 (0)