What is an ExecutorService
?
It is an interface that provides abstraction over creating, managing and scheduling tasks on threads. We only have to use this to execute tasks asynchronously.
Creating an ExecutorService
Most of the times, factory methods provided factory Executors
are enough for the use cases. However, we can also create ExecutorService
directly using ThreadPoolExecutor
.
val executorService: ExecutorService = ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())
Creating by using factory methods,
val exService: ExecutorService = Executors.newFixedThreadPool(10)
val singleExService: ExecutorService: Executors.newSingleThreadExecutor()
Schedule a task
ExecutorService
provides methods such as
execute
submit
invokeAny
andinvokeAll
executorService.execute(runnable)
val future: Future[Unit] = executorService.submit(runnable)
Shutting down
ExecutorService
won’t get shutdown automatically. It keeps waiting for new tasks to assign. We have to manually shut it down.
We can do so by using methods,
shutdown
shutdownNow
Using ExecutorService
In scala, we can either directly schedule tasks on executorService
or provide this to an ExecutionContext
.
With the previous approach, we have to manually convert java.Future
to scala.Future
. In latter approach, ExecutionContext
does everything by itself.
val ec: ExecutionContext = ExecutionContext.fromExecutor(exService)
val f: Future[Int] = Future {
printWithThread("From future")
1
}(using ec)