scala./ align = "left" / blokowanie-co to właściwie robi?

Spędziłem chwilę ucząc się tematu kontekstów wykonywania Scali, bazujących na modelach wątkowych i współbieżności. Czy możesz wyjaśnić, w jaki sposób scala.concurrent.blocking "Dostosuj zachowanie runtime" i "może poprawić wydajność lub uniknąć blokad" , jak opisano w scaladoc?

W Dokumentacja jest przedstawiona jako sposób oczekiwania na api, które nie implementuje Awaitable. (Być może również po prostu długie obliczenia powinny być zapakowane?).

Co to właściwie robi?

Podążanie za źródłem nie łatwo zdradza jego sekrety.

Author: matanster, 2015-03-16

1 answers

blocking ma działać jako wskazówka do ExecutionContext, że zawarty kod blokuje się i może prowadzić do głodu wątku. To da puli wątków szansę na odradzanie nowych wątków, aby zapobiec głodowi. To jest to, co oznacza "dostosuj zachowanie środowiska wykonawczego". Nie jest to jednak magia i nie będzie działać z każdym ExecutionContext.

Rozważ ten przykład:

import scala.concurrent._
val ec = scala.concurrent.ExecutionContext.Implicits.global

(0 to 100) foreach { n =>
    Future {
        println("starting Future: " + n)
        blocking { Thread.sleep(3000) }
        println("ending Future: " + n)
    }(ec)
}

Używa się domyślnego globalnego ExecutionContext. Uruchamiając kod tak, jak jest, zauważysz, że 100 Future s wszystkie są wykonywane natychmiast, ale jeśli usuniesz blocking, wykonają tylko kilka na raz. Domyślnie ExecutionContext będzie reagować na blokowanie połączeń (oznaczone jako takie) przez wywoływanie nowych wątków, a tym samym nie będzie przeciążone uruchomieniem Futures.

Teraz spójrz na ten przykład ze stałą pulą 4 wątków:

import java.util.concurrent.Executors
val executorService = Executors.newFixedThreadPool(4)
val ec = ExecutionContext.fromExecutorService(executorService)

(0 to 100) foreach { n =>
    Future {
        println("starting Future: " + n)
        blocking { Thread.sleep(3000) }
        println("ending Future: " + n)
    }(ec)
}

Ten ExecutionContext nie jest zbudowany do obsługi spawania nowych wątków, więc nawet z moim kodem blokującym otoczonym blocking, widać, że nadal będzie wykonywał tylko co najwyżej 4 Future s W czas. I dlatego mówimy, że "może poprawić wydajność lub uniknąć impasu" {47]} - to nie jest gwarantowane. Jak widzimy w tym drugim ExecutionContext, nie jest to w ogóle gwarantowane.

Jak to działa? Jako linked, blocking wykonuje ten kod:
BlockContext.current.blockOn(body)(scala.concurrent.AwaitPermission)

BlockContext.current pobiera BlockContext z bieżącego wątku, widzianego tutaj . A BlockContext jest zwykle po prostu Thread z BlockContext cecha zmieszana. Jak widać w źródle, jest albo przechowywany w ThreadLocal, albo jeśli go tam nie ma, jest wzór dopasowany z bieżącego wątku. Jeśli bieżący wątek nie jest BlockContext, to zamiast niego używany jest DefaultBlockContext.

Następny, blockOn jest wywoływany na bieżącym BlockContext. blockOn jest metodą abstrakcyjną w BlockContext, więc jej implementacja zależy od tego, jak ExecutionContext ją obsługuje. Jeśli przyjrzymy się implementacji dla DefaultBlockContext (gdy bieżący wątek nie jest BlockContext), widzimy, że blockOn W rzeczywistości nic tam nie robi. Więc użycie blocking w nie BlockContext oznacza, że nic specjalnego nie robi się w wszystkie, A kod jest uruchamiany tak, jak jest, bez skutków ubocznych.

A co z wątkami, które są BlockContext s? Na przykład w kontekście global, widzianym tutaj, blockOn robi coś więcej. Kopając głębiej, widać, że używa ForkJoinPool pod maską, z DefaultThreadFactory zdefiniowanym w tym samym fragmencie, używanym do wywoływania nowych wątków w ForkJoinPool. Bez implementacji blockOn z BlockContext (wątek), ForkJoinPool nie wie, że blokujesz i nie będzie próbował wywołać więcej wątków w odpowiedzi.

Scala ' s Await również używa blocking do jego implementacji.

 61
Author: Michael Zajac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-17 17:04:26