You should use special approaches to deal with multithreading, such as RxJava or coroutines. Using RxJava, you can easily process asynchronous events in several threads:
fun singleBake(): Single<Cake> {
return Single.fromCallable { bake() }.subscribeOn(Schedulers.computation())
}
fun reactiveOrder(amountOfCakes: Int): Single<List<Cake>> {
val baker = Baker()
return Observable.range(0, amountOfCakes)
.flatMapSingle { baker.singleBake() }
.toList()
}
.....................
Bakery().reactiveOrder(10)
.subscribe { cakes -> println("Number of cakes: ${cakes.size}")}
Use common patterns to synchronize the work of several threads:
val lock = Lock()
Bakery().reactiveOrder(10)
.doAfterTerminate { lock.unlock() }
.subscribe { cakes -> println("Number of cakes: ${cakes.size}")}
lock...