Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Nuevo Tema (tarea) .start () VS ThreadPoolExecutor.submit (tarea) en Android

En mi proyecto de Android tenía un montón de lugares donde tengo que ejecutar algún código de forma asincrónica (una solicitud web, llamada a db etc). No se trata de tareas largas (máximo unos segundos). Hasta ahora estaba haciendo este tipo de cosas con la creación de un nuevo hilo, pasando un nuevo ejecutables con la tarea. Pero recientemente he leído un artículo sobre los temas y la concurrencia en Java y entendido que la creación de un nuevo hilo para cada tarea no es una buena decisión.

Así que ahora he creado un ThreadPoolExecutor en mi clase de Application que contiene 5 subprocesos. Aquí está el código:

  • Android Studio: Gradle: error: no se puede encontrar la variable de símbolo
  • Error en el proyecto de construcción en Android Studio
  • ¿Cómo hacer una ventana emergente de diálogo "no me preguntes otra vez"? Androide
  • LG G4 no reconocido por Android Studio
  • Cómo puedo hacer referencia a una clase drawable en Android XML
  • Necesita una solución de trabajo para usar la pantalla de bloqueo de patrón Android en la aplicación personalizada (y no redireccionamientos de código fuente)
  •  public class App extends Application { private ThreadPoolExecutor mPool; @Override public void onCreate() { super.onCreate(); mPool = (ThreadPoolExecutor)Executors.newFixedThreadPool(5); } } 

    Y también tengo un método para enviar tareas ejecutables al ejecutor:

     public void submitRunnableTask(Runnable task){ if(!mPool.isShutdown() && mPool.getActiveCount() != mPool.getMaximumPoolSize()){ mPool.submit(task); } else { new Thread(task).start(); } } 

    Por lo tanto, cuando quiero ejecutar una tarea asincrónica en mi código obtener la instancia de la App y llamar al método submitRunnableTask pasando el ejecutables a ella. Como puedes ver, también compruebo si el grupo de subprocesos tiene subprocesos libres para ejecutar mi tarea, si no, creo un nuevo hilo (no creo que esto vaya a suceder, pero en cualquier caso …) T quiero que mi tarea de esperar en una cola y ralentizar la aplicación).

    En el método de devolución de llamada onTerminate de la Aplicación, onTerminate la agrupación.

    Así que mi pregunta es la siguiente: ¿Es este tipo de patrón mejor que la creación de nuevos hilos en código? ¿Qué ventajas y desventajas tiene mi nuevo enfoque? ¿Puede causar problemas que aún no conozco? ¿Me puede aconsejar algo mejor que esto para gestionar mis tareas asíncronas?

    PS Tengo alguna experiencia en Android y Java, pero estoy lejos de ser un gurú de concurrencia) Así que puede haber aspectos que no entiendo bien en este tipo de preguntas. Cualquier consejo será apreciado.

  • Android Studio: "libpng warning: iCCP: No reconoce el perfil sRGB conocido que ha sido editado"
  • ¿Cómo cambiar el diseño y el color del fondo del hilandero para android?
  • Adición de una carpeta de activos en Android Studio
  • Buscar un nuevo punto de control cuando cambia el punto final en la curva cúbica de Bézier
  • La llamada requiere el nivel 23 de API: error getForeground (), pero es un método FrameLayout ya que API 1
  • TextInputLayout setErrorEnabled no crea nuevo objeto TextView
  • 3 Solutions collect form web for “Nuevo Tema (tarea) .start () VS ThreadPoolExecutor.submit (tarea) en Android”

    Esta respuesta supone que sus tareas son cortas

    ¿Es este tipo de patrón mejor que crear nuevos hilos en código?

    Es mejor, pero aún está lejos de ser ideal. Sigue creando subprocesos para tareas cortas . En su lugar sólo tiene que crear un tipo diferente de grupo de subprocesos – por ejemplo, por Executors.newScheduledThreadPool(int corePoolSize) .

    ¿Cuál es la diferencia en el comportamiento?

    • Un FixedThreadPool siempre tendrá un conjunto de subprocesos a utilizar y si todos los subprocesos están ocupados, una nueva tarea se colocará en una cola.
    • A (predeterminado) ScheduledThreadPool , creado por la clase Executors , tiene un grupo de subprocesos mínimo que guarda, incluso cuando está inactivo. Si todos los subprocesos están ocupados cuando una nueva tarea llega, crea un nuevo subproceso para él y desecha el subproceso 60 segundos después de haberlo hecho, a menos que sea necesario de nuevo.

    El segundo puede permitir que no cree nuevos hilos por usted mismo. Este comportamiento se puede lograr sin la parte "programada", pero tendrá que construir el ejecutor usted mismo. El constructor es

     public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) 

    Las diversas opciones le permiten afinar el comportamiento.

    Si algunas tareas son largas …

    Y me refiero a largo. Como en la mayoría de la vida útil de la aplicación (conexión en tiempo real en 2 vías, puerto de servidor, receptor de multicast, etc.). En ese caso, poner su Runnable en un ejecutor es perjudicial – los ejecutores Runnable no están diseñados para hacerle frente, y su rendimiento se deteriorará.

    Piense en su grupo de hilos fijo – si tiene 5 tareas largas, entonces cualquier nueva tarea generará un nuevo hilo, destruyendo completamente cualquier posible ganancia de la piscina. Si utiliza un ejecutor más flexible – algunos hilos serán compartidos, pero no siempre.

    La regla de oro es

    • Si es una tarea corta – use un ejecutor.
    • Si es una tarea larga – asegúrese de que su ejecutor puede manejarlo (es decir, o bien no tiene un tamaño máximo de la piscina, o suficientes hilos máximos para hacer frente a 1 hilo más se ha ido por un tiempo)
    • Si se trata de un proceso paralelo que debe ejecutarse siempre junto a su subproceso principal, utilice otro subproceso.

    Para responder a su pregunta – Sí, utilizar Executor es mejor que crear nuevos hilos porque:

    1. Executor proporciona una selección de diferentes conjuntos de subprocesos. Permite la reutilización de los hilos ya existentes, lo que aumenta el rendimiento, ya que la creación de subprocesos es una operación costosa.
    2. En caso de que un hilo muera, Executor puede reemplazarlo con un nuevo hilo sin afectar la aplicación.
    3. Los cambios en las directivas multi-subprocesos son mucho más fáciles, ya que solo se necesita cambiar la implementación Ejecutor.

    Basándome en el comentario de Ordous he modificado mi código para trabajar con sólo una piscina.

     public class App extends Application { private ThreadPoolExecutor mPool; @Override public void onCreate() { super.onCreate(); mPool = new ThreadPoolExecutor(5, Integer.MAX_VALUE, 1, TimeUnit.MINUTES, new SynchronousQueue<Runnable>()); } } public void submitRunnableTask(Runnable task){ if(!mPool.isShutdown() && mPool.getActiveCount() != mPool.getMaximumPoolSize()){ mPool.submit(task); } else { new Thread(task).start(); // Actually this should never happen, just in case... } } 

    Por lo tanto, espero que esto puede ser útil para alguien más, y si las personas más experimentadas tienen algunos comentarios sobre mi enfoque, voy a apreciar sus comentarios.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.