Читая это руководство о том, как анализировать изображения, поступающие непосредственно с камеры; в примере кода внизу страницы внезапно появляется новая переменная executor:
imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer { imageProxy ->
Посмотрел, Executor — это просто еще одна абстракция распараллеливания. Как мне его получить? Есть ли что-то подобное?
androidThreadPool.getExecutor()
На самом деле я нашел один:
Context.getMainExecutor()
Если я правильно понимаю, это приведет к выполнению Runnable в основном потоке. Однако я предполагаю, что смысл предоставления Executor для ImageAnalyzer заключается в том, чтобы не запускать его в основном потоке.
Или мне нужно создать своего собственного Исполнителя? Это обычная практика?
this would execute the Runnable on the main thread. Runnable — довольно старый интерфейс, в новом коде я бы по крайней мере рассмотрел возможность использования Callable<T> вместо него.
Ссылка EZ на ExecutorSevice: Developer.android.com/reference/java/util/concurrent/… Существует также пул ForkJoin, который может предоставить своих собственных исполнителей, если fork-join подходит для вашего варианта использования.
Пожалуйста, не отмечайте одновременно java и kotlin.
Фирмы не согласны с тегами как для Java, так и для Kotlin; ответы обычно совпадают и, конечно же, на такой вопрос.
для Java я бы проверил документацию Executor: "... Класс Executors предоставляет удобные фабричные методы для этих Исполнителей. ..."
Я ждал этого, но должен согласиться с Луи @MarcinOrlowski Java и Kotlin настолько разные, что уместно пометить оба. Я ответил, основываясь на знании Java, но я бы никогда не увидел этот вопрос, если бы он был отмечен только тегом Kotlin.
@markspace Runnable — отличный интерфейс. Разница между Runnable и Callable заключается в том, нужно ли вам вернуть значение. Вам следует предпочесть тот, который делает то, что вам нужно, а не только тот, который более новый.




Исполнитель — это просто еще одна абстракция распараллеливания.
Нет, не «просто еще один». Платформа Executors стала важной вехой в развитии Java. Этот фреймворк снял с плеч Java-программистов бремя управления потоками, значительно упростив параллельную работу.
ExecutorService, а не ExecutorИнтерфейс Executor — не самая часто используемая часть. Этот интерфейс определяет метод выполнить, который может запускать вашу задачу в фоновом потоке или с тем же успехом запускать задачу в текущем потоке.
Если вы знаете, что вам нужен фоновый поток, используйте реализацию субинтерфейса ExecutorService с его методами, такими как submit.
как мне его получить
Обычно мы получаем неопределенную реализацию ExecutorService, вызывая удобный фабричный метод класса Executors.
Возможно, вам понадобится служба-исполнитель, поддерживаемая пулом с любым количеством потоков. Используйте это только в том случае, если вы знаете, что количество одновременных задач ограничено, чтобы не перегружать вашу машину.
ExecutorService es = Executors.newCachedThreadPool() ;
Возможно, вам понадобится служба-исполнитель, поддерживаемая пулом из определенного количества потоков.
ExecutorService es = Executors.newFixedThreadPool( maxThreadsCount ) ;
В современной Java версии 21+ мы используем виртуальные потоки для большинства целей. Я предполагаю, что Android не предлагает виртуальные потоки и не будет в ближайшее время.
ExecutorService es = Executors.newVirtualThreadPerTaskExecutor() ;
Любая из этих служб-исполнителей может выполнять ваши задачи, которые вы определяете как Runnable или Callable.
Или мне нужно создать своего собственного Исполнителя?
Нет, это очень редкая ситуация, когда вам понадобится услуга специального исполнителя.
Является ли [создание собственного исполнителя] обычной практикой?
Нет.
Цель платформы «Исполнители» — избежать работы с низкоуровневыми деталями манипулирования потоками и задачами. Несколько хороших реализаций ExecutorService включены в состав Java и доступны вам через класс Executors.
Предостережение: я не знаю Android. Мои комментарии здесь относятся к платформе Java. Мои комментарии могут также относиться к Android; Я просто не знаю.
Одна вещь, которую я не сразу заметил, это то, что ExecutorService на самом деле реализует интерфейс Executor. При этом получить Executor от Executors действительно несложно.
@ user1785730 Да, каждый объект ExecutorService также является объектом Executor. Но если вы относитесь к нему как к Executor, у вас будет доступ только к методу execute, который может работать или не работать в фоновом потоке. В качестве Executor у вас не будет доступа к методам submit и invoke…, которые гарантированно будут работать в фоновых потоках.
Я не программирую Android (хотя учусь), но, похоже, это работает так же, как и обычная Java. Если вы прочитаете эту ссылку на «Исполнители», вы увидите, что «Исполнитель» — это интерфейс, а далее в документации, что класс «ExecutorService» предоставляется как реализация. В классе
Executorsесть фабричные методы, которые вы можете использовать. Например:pool = Executors.newFixedThreadPool(poolSize);