Advertisement
Kostiggig

ConcurrentHashMap task

May 14th, 2023
916
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.38 KB | None | 0 0
  1. package concurrent_hash_map.merge_requests
  2.  
  3. import java.util.concurrent.ConcurrentHashMap
  4. import kotlin.concurrent.thread
  5. import kotlin.random.Random
  6.  
  7. /*Нужно написать имплементацию интерфейсаCommandExecutor.
  8. При этом нужно сделать так чтобы если мы имели несколько одинаковых запросов одновременно,
  9. мы выполняли запрос один раз, а не несколько и затем просто дублировали информацию между экранами.
  10.  
  11. Метод requestAsync не должен блокировать вызывающий поток,
  12. а ответ должен приходить в метод onResponse.*/
  13.  
  14. interface CommandExecutor {
  15.  
  16.     fun requestAsync(url: String, onResponse: (String) -> Unit)
  17. }
  18.  
  19. class CommandExecutorImpl : CommandExecutor {
  20.  
  21.     private val map = ConcurrentHashMap<String, MutableList<(String) -> Unit>>()
  22.     private val requestIsMaking = ConcurrentHashMap<String, Boolean>()
  23.  
  24.     override fun requestAsync(url: String, onResponse: (String) -> Unit) {
  25.         if (map.contains(url)) {
  26.             map.computeIfPresent(url) { _, v ->
  27.                 v.apply { add(onResponse) }
  28.             }
  29.         } else {
  30.             map.putIfAbsent(url, mutableListOf())
  31.             map.computeIfPresent(url) { _, v ->
  32.                 v.apply { add(onResponse) }
  33.             }
  34.  
  35.             if(requestIsMaking.putIfAbsent(url, true) == null) makeRequest(url)
  36.         }
  37.     }
  38.  
  39.     private fun makeRequest(url: String) {
  40.         println("Make request by ${Thread.currentThread().name} for $url")
  41.  
  42.         Thread.sleep(Random.nextLong(5000)) // simulate io operation from 0 to 5000 ms
  43.         (map[url] ?: mutableListOf()).forEach { consumer ->
  44.             consumer.invoke("Response for $url")
  45.         }
  46.     }
  47. }
  48.  
  49.  
  50. fun main() {
  51.     val urls = listOf(
  52.         "url1",
  53.         "url2",
  54.         "url3"
  55.     )
  56.  
  57.     val commandExecutor = CommandExecutorImpl()
  58.  
  59.     for(i in 0..10) {
  60.         val urlIndex = Random.nextInt(0, urls.size)
  61.         thread(name = "Thread $i") {
  62.             val threadName = Thread.currentThread().name
  63.             commandExecutor.requestAsync(urls[urlIndex]) {
  64.                 println("Consume response by $threadName - $it")
  65.             }
  66.         }
  67.     }
  68.  
  69.     Thread.sleep(10000)
  70. }
  71.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement