Java Futures

As callback style tends to be hard to maintain, other styles have emerged in recent years. One of these styles is futures. A future is a computation that may complete in the future. When we invoke the Future.get method, it will obtain its result, but we also block the thread:

import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

class
FutureUserService(private val userClient: UserClient,
private val factClient: FactClient,
private val userRepository: UserRepository,
private val factRepository: FactRepository) : UserService {
override fun getFact(id: UserId): Fact {

val executor = Executors.newFixedThreadPool(2)

val user = executor.submit<User?> { userRepository.getUserById(id) }.get()
return if (user == null) {
val userFromService = executor.submit<User> { userClient.getUser(id) }.get()
executor.submit { userRepository.insertUser(userFromService) }
getFact(userFromService, executor)
} else {
executor.submit<Fact> {
factRepository.getFactByUserId(id) ?: getFact(user, executor)
}.get()
}.also {
executor.shutdown()
}
}

private fun getFact(user: User, executor: ExecutorService): Fact {
val fact = executor.submit<Fact> { factClient.getFact(user) }.get()
executor.submit { factRepository.insertFact(fact) }
return fact
}
}

The implementation with futures is very similar to our synchronous implementation, but with those weird submit and get functions all over the place. We also have Executor that we need to take care of. Total time is around 1,200 milliseconds, with many threads created, more than in the callback example. One possible option is to have Executor per instance or globally, but in that case, we also need to have some way to manage its life cycle.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.220.16