Skip to content

Instantly share code, notes, and snippets.

@orionll
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orionll/9771204 to your computer and use it in GitHub Desktop.
Save orionll/9771204 to your computer and use it in GitHub Desktop.
Example which demonstrates how Scala scales out while Java does not
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import com.google.common.base.Stopwatch;
import com.google.common.util.concurrent.Uninterruptibles;
public class Main {
public static void main(String[] args) throws Exception {
Stopwatch sw = Stopwatch.createStarted();
ForkJoinTask<Integer> future = ForkJoinPool.commonPool().submit(() -> {
ForkJoinTask<Integer> f1 = async(() -> status(1));
ForkJoinTask<Integer> f2 = async(() -> status(2));
ForkJoinTask<Integer> f3 = async(() -> status(3));
ForkJoinTask<Integer> f4 = async(() -> status(4));
ForkJoinTask<Integer> f5 = async(() -> status(5));
ForkJoinTask<Integer> f6 = async(() -> status(6));
return f1.join() + f2.join() + f3.join() + f4.join() + f5.join() + f6.join(); // join blocks the thread
});
System.out.println(future.get());
System.out.println("Finished in " + sw.stop()); // Takes 3 seconds on my machine (does not utilize all the threads)
}
public static int status(int i) {
System.out.println(Thread.currentThread().getName() + " " + i);
// Imitating long running computation
Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
return i;
}
public static <T> ForkJoinTask<T> async(Supplier<T> supplier) {
return new RecursiveTask<T>() {
@Override
protected T compute() {
return supplier.get();
}
}.fork();
}
}
import scala.async.Async.{async, await}
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.concurrent.Await
import scala.concurrent.duration._
import java.util.concurrent.ForkJoinPool
import com.google.common.base.Stopwatch
object Main extends App {
implicit val executionContext = ExecutionContext.fromExecutorService(
new ForkJoinPool(Runtime.getRuntime().availableProcessors() - 1))
val sw = Stopwatch.createStarted
val future: Future[Int] = async {
val f1 = async { status(1) }
val f2 = async { status(2) }
val f3 = async { status(3) }
val f4 = async { status(4) }
val f5 = async { status(5) }
val f6 = async { status(6) }
await(f1) + await(f2) + await(f3) + await(f4) + await(f5) + await(f6) // looks like await must block the thread but it doesn't
}
println(Await.result(future, 1.minutes))
println(s"Finished in ${sw.stop}") // Takes 2 seconds (6 tasks per 3 threads)
def status(i: Int): Int = {
println(Thread.currentThread().getName() + " " + i);
// Imitating long running computation
Thread.sleep(1000)
i;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment