best practice for actors thread re-use

27 views
Skip to first unread message

Yair Ogen

unread,
Apr 2, 2014, 5:42:25 AM4/2/14
to jumi-tes...@googlegroups.com
I'm wondering what would be the best approach for re-using threads. I know that when you create an ActorThread each binded actorref created from that ActorThread will use the same Thread. So if I want to create multiple actor refs, each using a different thread, I must stop teh actorThread such that it can server anotehr actor. Is that right?

See the following example. Replace my for loop with a business logic running behind a thread pool (e.g. a web-app handler thread pool for example). Does the below sound like a right best-practice? Or maybe calling the stop thread API all the time is costly? 

public class ActorsTest {

    private static final int NUM_OF_ITER = 100;


    @Test
    public void actorsTest() throws Exception{

        CountDownLatch countDownLatch = new CountDownLatch(NUM_OF_ITER);

        FooImpl foo = new FooImpl();

        Actors actors = new MultiThreadedActors(
                Executors.newFixedThreadPool(3),
                new DynamicEventizerProvider(),
                new CrashEarlyFailureHandler(),
                new NullMessageListener()
        );


        for (int i = 1; i <= NUM_OF_ITER; i++) {
            ActorThread actorThread = actors.startActorThread();
            ActorRef<Foo> fooActorRef = actorThread.bindActor(Foo.class, foo);
            fooActorRef.tell().print("message: " + i, countDownLatch);
            actorThread.stop();
        }

        countDownLatch.await();

    }

    public static interface Foo {
        void print(String msg, CountDownLatch countDownLatch);
    }

    public static class FooImpl implements Foo {
        @Override
        public void print(String msg, CountDownLatch countDownLatch) {
            System.out.println("[" + Thread.currentThread().getName() + ":"+Thread.currentThread().getId()+"] " + msg);
            countDownLatch.countDown();
        }
    }
}

Esko Luontola

unread,
Apr 2, 2014, 4:39:25 PM4/2/14
to jumi-tes...@googlegroups.com
Hi

The usage pattern in your code example does not require actors, because
there is no communication between them. A better tool for it is a plain
old ExecutorService like this:


public class ExampleTest {

private static final int NUM_OF_ITER = 100;

@Test
public void example() throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(3);
List<Future<?>> dones = new ArrayList<>();

for (int i = 1; i <= NUM_OF_ITER; i++) {
final String message = "message: " + i;
dones.add(executor.submit(new Runnable() {
@Override
public void run() {
print(message);
}
}));
}

for (Future<?> done : dones) {
done.get();
}
}

public static void print(String msg) {
System.out.println("[" + Thread.currentThread().getName() + ":"
+ Thread.currentThread().getId() + "] " + msg);
}
}


Does this fit your actual use case? If not, please tell more information.

--
Esko Luontola
www.orfjackal.net

Yair Ogen

unread,
Apr 3, 2014, 3:06:07 AM4/3/14
to jumi-tes...@googlegroups.com
Naturally, I thought of this. However, this sample is, well, just a sample. In real life the logic here would be a http request which I want to do asynchronously.

  1. I don't want to manage the "mail box" my self.
  2. I'd like to get a framework that captures errors properly and don't want to re-invent the wheel here.
Isn't this (among others) what actors are for?

Thanks,

Yair

Esko Luontola

unread,
Apr 4, 2014, 3:40:45 AM4/4/14
to jumi-tes...@googlegroups.com
Yair Ogen wrote on 3.4.2014 10:06:
> 1. I don't want to manage the "mail box" my self.
> 2. I'd like to get a framework that captures errors properly and don't
> want to re-invent the wheel here.
>
> Isn't this (among others) what actors are for?

Those two things in themselves do not require the complexity of actors.
The first point at its simplest can be covered with a thread pool or a
single queue. The second point can be covered with a single try-catch
block in the correct place.

The core idea of the actor model
(http://en.wikipedia.org/wiki/Actor_model) is concurrent computation
(not necessarily parallel) where actors make decisions based on local
state and communicate asynchronously by sending messages to each other.

Additionally, Jumi Actors focuses only on the essence of actors -
asynchronous communication and local state - and does not have extra
features for parallel computation and load sharing. Those things you can
find in Akka Actors
(http://doc.akka.io/docs/akka/snapshot/scala/dispatchers.html), but with
Jumi Actors you should use a thread pool when you want to process the
same kinds of tasks in parallel.

--
Esko Luontola
www.orfjackal.net
Reply all
Reply to author
Forward
0 new messages