One of the coolest new futures of Java 1.5 is the Executor framework, which allows you to asynchronously execute
your tasks, logical units of works, such as database query, complex calculation, image rendering etc. So one nice
way of executing such tasks would be running them asynchronously and doing other things meanwhile. When ready, get
the result and move on. If execution of the task takes longer than expected, you may consider canceling the task
execution. In Java Executor framework, tasks are implemented as
java.util.concurrent.Callable
andjava.util.Runnable
.
import java.util.concurrent.Callable; import java.io.Serializable; public class Echo implements Callable<String>, Serializable { String input = null; public Echo() { } public Echo(String input) { this.input = input; } public String call() { return Hazelcast.getCluster().getLocalMember().toString() + ":" + input; } }
Echo callable above, for instance, in its
call()
method, is returning the local member and the input passed in. Remember that
Hazelcast.getCluster().getLocalMember()
returns the local member and
toString()
returns the member's address
(ip + port)
in String form, just to see which member actually executed the code for our example. Of course, call() method can do
and return anything you like.
Executing a task by using executor framework is very straight forward. Simply obtain a
ExecutorService
instance, generally via
Executors
and submit the task which returns aFuture
. After executing task, you don't have to wait for
execution to complete, you can process other things and when ready use the future object to retrieve the result as
show in code below.
ExecutorService executorService = Executors.newSingleThreadExecutor(); Future<String> future = executorService.submit (new Echo("myinput")); //while it is executing, do some useful stuff //when ready, get the result of your execution String result = future.get();
Distributed executor service is a distributed implementation of java.util.concurrent.ExecutorService.
It allows you to execute your code in cluster. In this chapter, all the code samples are based on the Echo class
above.
Please note that Echo class is
Serializable
.
You can ask Hazelcast to execute your code (Runnable, Callable
):
on a specific cluster member you choose.
on the member owning the key you choose.
on the member Hazelcast will pick.
on all or subset of the cluster members.
import com.hazelcast.core.Member; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.MultiTask; import com.hazelcast.core.DistributedTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.FutureTask; import java.util.concurrent.Future; import java.util.Set; public void echoOnTheMember(String input, Member member) throws Exception { FutureTask<String> task = new DistributedTask<String>(new Echo(input), member); ExecutorService executorService = Hazelcast.getExecutorService(); executorService.execute(task); String echoResult = task.get(); } public void echoOnTheMemberOwningTheKey(String input, Object key) throws Exception { FutureTask<String> task = new DistributedTask<String>(new Echo(input), key); ExecutorService executorService = Hazelcast.getExecutorService(); executorService.execute(task); String echoResult = task.get(); } public void echoOnSomewhere(String input) throws Exception { ExecutorService executorService = Hazelcast.getExecutorService(); Future<String> task = executorService.submit(new Echo(input)); String echoResult = task.get(); } public void echoOnMembers(String input, Set<Member> members) throws Exception { MultiTask<String> task = new MultiTask<String>(new Echo(input), members); ExecutorService executorService = Hazelcast.getExecutorService(); executorService.execute(task); Collection<String> results = task.get(); }
Note that you can obtain the set of cluster members via
Hazelcast.getCluster().getMembers()
call.
You can also extend the
MultiTask
class to override
set(V result), setException(Throwable exception), done()
methods for custom behaviour.
Just like
java.util.concurrent.FutureTask.get() , MultiTask.get()
will throw
java.util.concurrent.ExecutionException
if any of the executions throws exception.