[{"data":1,"prerenderedAt":1875},["ShallowReactive",2],{"navigation_docs":3,"-ejemplos-ejemplo-06":298,"-ejemplos-ejemplo-06-surround":1870},[4,18,70,105,149,178,212,257],{"title":5,"path":6,"stem":7,"children":8,"icon":17},"Evaluación","\u002Fintroduction","1.introduction\u002F1.index",[9,12],{"title":10,"path":6,"stem":7,"icon":11},"Método de Evaluación","i-iconamoon-cheque-bold",{"title":13,"path":14,"stem":15,"icon":16},"Plataforma de Aprendizaje","\u002Fintroduction\u002Fplataforma","1.introduction\u002F2.plataforma","i-lucide-book-marked","i-lucide-house",{"title":19,"path":20,"stem":21,"children":22,"icon":25},"Interfaz Gráfica de Usuario","\u002Fgui","2.gui\u002F01.index",[23,26,30,34,38,42,46,50,54,58,62,66],{"title":24,"path":20,"stem":21,"icon":25},"¿Qué es una Interfaz Gráfica de Usuario (GUI)?","i-carbon-gui-management",{"title":27,"path":28,"stem":29,"icon":25},"Creación de Interfaces Gráficas de Usuario (GUI)","\u002Fgui\u002Fbuild-gui","2.gui\u002F02.build-gui",{"title":31,"path":32,"stem":33,"icon":25},"Componentes Básicos de Swing","\u002Fgui\u002Fcomponentes-basicos","2.gui\u002F03.componentes-basicos",{"title":35,"path":36,"stem":37},"El componente JFrame","\u002Fgui\u002Fjframe","2.gui\u002F04.jframe",{"title":39,"path":40,"stem":41},"El componente JPanel","\u002Fgui\u002Fjpanel","2.gui\u002F05.jpanel",{"title":43,"path":44,"stem":45},"El componente JButton","\u002Fgui\u002Fjbutton","2.gui\u002F06.jbutton",{"title":47,"path":48,"stem":49,"icon":25},"Elementos de texto en interfaces gráficas con Swing","\u002Fgui\u002Ftext","2.gui\u002F07.text",{"title":51,"path":52,"stem":53},"Elementos Visuales","\u002Fgui\u002Felementos-visuales","2.gui\u002F08.elementos-visuales",{"title":55,"path":56,"stem":57,"icon":25},"Eventos en Swing","\u002Fgui\u002Feventos","2.gui\u002F09.eventos",{"title":59,"path":60,"stem":61,"icon":25},"Controles en Swing","\u002Fgui\u002Fcontroles","2.gui\u002F10.controles",{"title":63,"path":64,"stem":65,"icon":25},"Atributos Comunes de los Componentes de Diseño","\u002Fgui\u002Fatributos-comunes","2.gui\u002F11.atributos-comunes",{"title":67,"path":68,"stem":69,"icon":25},"Layouts","\u002Fgui\u002Flayout","2.gui\u002F12.layout",{"title":71,"icon":25,"path":72,"stem":73,"children":74,"page":104},"Personalización","\u002Fpersonalizacion","3.personalizacion",[75,79,84,88,92,96,100],{"title":76,"path":77,"stem":78},"Jerarquía de clases en Swing","\u002Fpersonalizacion\u002Fjerarquia","3.personalizacion\u002F01.jerarquia",{"title":80,"path":81,"stem":82,"icon":83},"Personalización Inicial de Componentes Swing","\u002Fpersonalizacion\u002Fpersonalizacion-inicial","3.personalizacion\u002F02.personalizacion-inicial","i-carbon-palette",{"title":85,"path":86,"stem":87,"icon":83},"Tema y Personalización Avanzada en Swing","\u002Fpersonalizacion\u002Ftheme","3.personalizacion\u002F03.theme",{"title":89,"path":90,"stem":91,"icon":83},"Pintando en Swing","\u002Fpersonalizacion\u002Fpaint","3.personalizacion\u002F04.paint",{"title":93,"path":94,"stem":95,"icon":83},"Mi Tema 1: Comenzando con la Personalización","\u002Fpersonalizacion\u002Ftheme-start","3.personalizacion\u002F05.theme-start",{"title":97,"path":98,"stem":99,"icon":83},"UI Delegates: Personalizando la Apariencia de los Componentes","\u002Fpersonalizacion\u002Fui-delegates","3.personalizacion\u002F06.ui-delegates",{"title":101,"path":102,"stem":103,"icon":83},"Empleado delegadores de UI para personalizar la apariencia de los componentes","\u002Fpersonalizacion\u002Ftheme-02","3.personalizacion\u002F07.theme-02",false,{"title":106,"path":107,"stem":108,"children":109,"icon":148},"Programación concurrente","\u002Fconcurrencia","4.concurrencia\u002F01.index",[110,112,116,120,124,128,132,136,140,144],{"title":111,"path":107,"stem":108,"icon":83},"¿Qué es la concurrencia?",{"title":113,"path":114,"stem":115,"icon":83},"Unidades de Ejecución","\u002Fconcurrencia\u002Funidades-ejecucion","4.concurrencia\u002F02.unidades-ejecucion",{"title":117,"path":118,"stem":119,"icon":83},"Programa de flujo único y de flujo múltiple","\u002Fconcurrencia\u002Fflujos","4.concurrencia\u002F03.flujos",{"title":121,"path":122,"stem":123,"icon":83},"Hilos con Thread y Runnable","\u002Fconcurrencia\u002Fthread-runnable","4.concurrencia\u002F04.thread-runnable",{"title":125,"path":126,"stem":127},"Paralelismo V.S. Concurrencia","\u002Fconcurrencia\u002Fparalelismo","4.concurrencia\u002F05.paralelismo",{"title":129,"path":130,"stem":131,"icon":83},"Problemas clásicos de concurrencia","\u002Fconcurrencia\u002Fproblemas","4.concurrencia\u002F06.problemas",{"title":133,"path":134,"stem":135,"icon":83},"Emulando condiciones de carrera en Java","\u002Fconcurrencia\u002Fcondiciones-carrera","4.concurrencia\u002F07.condiciones-carrera",{"title":137,"path":138,"stem":139,"icon":83},"Semáforos en Java","\u002Fconcurrencia\u002Fsemaforos","4.concurrencia\u002F08.semaforos",{"title":141,"path":142,"stem":143,"icon":83},"La clase Timer en Java Swing","\u002Fconcurrencia\u002Ftimer","4.concurrencia\u002F09.timer",{"title":145,"path":146,"stem":147,"icon":83},"Algoritmos de ordenamiento de procesos","\u002Fconcurrencia\u002Falgoritmos-procesos","4.concurrencia\u002F10.algoritmos-procesos","i-carbon-parallel-groups",{"title":150,"path":151,"stem":152,"children":153,"icon":177},"Acceso a datos","\u002Fdatos","5.datos\u002F01.index",[154,157,161,165,169,173],{"title":155,"path":151,"stem":152,"icon":156},"Java y las bases de datos","i-carbon-database",{"title":158,"path":159,"stem":160},"Cliente Servidor","\u002Fdatos\u002Fcliente-servidor","5.datos\u002F02.cliente-servidor",{"title":162,"path":163,"stem":164},"CRUD","\u002Fdatos\u002Fcrud","5.datos\u002F03.crud",{"title":166,"path":167,"stem":168},"Sentencias Preparadas con JDBC","\u002Fdatos\u002Fsentencia-preparada","5.datos\u002F04.sentencia-preparada",{"title":170,"path":171,"stem":172},"DAO (Data Access Object)","\u002Fdatos\u002Fdao","5.datos\u002F05.dao",{"title":174,"path":175,"stem":176},"Usando Hibernate ORM","\u002Fdatos\u002Form","5.datos\u002F06.orm","i-gravity-ui-database-fill",{"title":179,"path":180,"stem":181,"children":182,"icon":211},"Programación móvil","\u002Fmovil","6.movil\u002F01.index",[183,186,191,195,199,203,207],{"title":184,"path":180,"stem":181,"icon":185},"¿Qué es Android y Kotlin?","i-carbon-mobile",{"title":187,"path":188,"stem":189,"icon":190},"¿Qué es Android Studio?","\u002Fmovil\u002Fandroid-studio","6.movil\u002F02.android-studio","i-carbon-application",{"title":192,"path":193,"stem":194,"icon":190},"¿Qué es Jetpack Compose?","\u002Fmovil\u002Fjetpack-compose","6.movil\u002F03.jetpack-compose",{"title":196,"path":197,"stem":198},"Filas y Columnas con Jetpack Compose","\u002Fmovil\u002Ffilas-columnas","6.movil\u002F04.filas-columnas",{"title":200,"path":201,"stem":202,"icon":190},"Componentes Básicos en Jetpack Compose","\u002Fmovil\u002Fcomponentes-basicos","6.movil\u002F05.componentes-basicos",{"title":204,"path":205,"stem":206,"icon":190},"Las Intenciones en Android con Jetpack Compose","\u002Fmovil\u002Fintentions","6.movil\u002F06.intentions",{"title":208,"path":209,"stem":210,"icon":190},"Navegación en Android con Jetpack Compose","\u002Fmovil\u002Fnavegacion","6.movil\u002F07.navegacion","phone_android",{"title":213,"icon":25,"path":214,"stem":215,"children":216,"page":104},"Ejemplos","\u002Fejemplos","7.ejemplos",[217,221,225,229,233,237,241,245,249,253],{"title":218,"path":219,"stem":220},"Ejemplo 01: Creando un validador abstracto de expresiones","\u002Fejemplos\u002Fejemplo-01","7.ejemplos\u002F01.ejemplo-01",{"title":222,"path":223,"stem":224},"Ejemplo 02: Diferencias de validar un JTextField y un JFormattedTextField","\u002Fejemplos\u002Fejemplo-02","7.ejemplos\u002F02.ejemplo-02",{"title":226,"path":227,"stem":228},"Ejemplo 03: Creando una Aplicación con GUI en Java Swing","\u002Fejemplos\u002Fejemplo-03","7.ejemplos\u002F03.ejemplo-03",{"title":230,"path":231,"stem":232},"Ejemplo 4: Estilizando componentes Swing con Delegadores","\u002Fejemplos\u002Fejemplo-04","7.ejemplos\u002F04.ejemplo-04",{"title":234,"path":235,"stem":236,"icon":83},"Ejemplo 5: Uso de Hilos con Thread y Runnable","\u002Fejemplos\u002Fejemplo-05","7.ejemplos\u002F05.ejemplo-05",{"title":238,"path":239,"stem":240,"icon":83},"Ejemplo 06: Manejando Hilos de formas Diferentes en Java","\u002Fejemplos\u002Fejemplo-06","7.ejemplos\u002F06.ejemplo-06",{"title":242,"path":243,"stem":244,"icon":83},"Ejemplo 7: Condiciones de carrera en Java","\u002Fejemplos\u002Fejemplo-07","7.ejemplos\u002F07.ejemplo-07",{"title":246,"path":247,"stem":248,"icon":83},"Ejemplo 8: Control de acceso a recursos compartidos con semáforos","\u002Fejemplos\u002Fejemplo-08","7.ejemplos\u002F08.ejemplo-08",{"title":250,"path":251,"stem":252,"icon":83},"Ejemplo 9: El restaurante y los pedidos","\u002Fejemplos\u002Fejemplo-09","7.ejemplos\u002F09.ejemplo-09",{"title":254,"path":255,"stem":256},"Ejemplo 10: Proceso FIFO (First In, First Out) con Semáforos y Swing","\u002Fejemplos\u002Fejemplo-10","7.ejemplos\u002F10.ejemplo-10",{"title":258,"icon":25,"path":259,"stem":260,"children":261,"page":104},"Actividades","\u002Factividades","8.actividades",[262,266,270,274,278,282,286,290,294],{"title":263,"path":264,"stem":265,"icon":25},"Actividad 1: Introducción al diseño de interfaces","\u002Factividades\u002Fact-01","8.actividades\u002F01.act-01",{"title":267,"path":268,"stem":269,"icon":25},"Actividad 2: Diseño de wireframes y prototipos","\u002Factividades\u002Fact-02","8.actividades\u002F02.act-02",{"title":271,"path":272,"stem":273,"icon":25},"Actividad 3: Propuesta de Proyecto y Wireframe inicial","\u002Factividades\u002Fact-03","8.actividades\u002F03.act-03",{"title":275,"path":276,"stem":277,"icon":83},"Actividad 4: Temas y Componentes Personalizados en Swing","\u002Factividades\u002Fact-04","8.actividades\u002F04.act-04",{"title":279,"path":280,"stem":281,"icon":83},"Actividad 5: Explicando la Concurrencia a un Niño de 5 Años","\u002Factividades\u002Fact-05","8.actividades\u002F05.act-05",{"title":283,"path":284,"stem":285,"icon":83},"Actividad 6: Simulación de una cocina con múltiples chefs (hilos)","\u002Factividades\u002Fact-06","8.actividades\u002F06.act-06",{"title":287,"path":288,"stem":289,"icon":83},"Actividad 7: Sistema de retiro bancario","\u002Factividades\u002Fact-07","8.actividades\u002F07.act-07",{"title":291,"path":292,"stem":293,"icon":83},"Actividad 8: Simulación de Round Robin con hilos e Interfaz Gráfica","\u002Factividades\u002Fact-08","8.actividades\u002F08.act-08",{"title":295,"path":296,"stem":297,"icon":83},"Actividad 9: CRUD con Hibernate y Swing","\u002Factividades\u002Fact-09","8.actividades\u002F09.act-09",{"id":299,"title":238,"body":300,"description":1863,"extension":1864,"links":1865,"meta":1866,"navigation":1867,"path":239,"seo":1868,"stem":240,"__hash__":1869},"docs\u002F7.ejemplos\u002F06.ejemplo-06.md",{"type":301,"value":302,"toc":1848},"minimark",[303,324,329,332,336,360,367,746,752,1266,1273,1498,1502,1505,1513,1516,1520,1530,1550,1553,1559,1563,1569,1572,1580,1789,1802,1825,1828,1832,1844],[304,305,306,307,311,312,315,316,319,320,323],"p",{},"En este ejemplo, vamos a explorar diferentes formas de manejar hilos en Java. Veremos cómo crear hilos utilizando la clase ",[308,309,310],"code",{},"Thread"," y la interfaz ",[308,313,314],{},"Runnable",", así como el uso de las funciones ",[308,317,318],{},"sleep",", ",[308,321,322],{},"join"," e interrupciones para controlar la ejecución de los hilos.",[325,326,328],"h2",{"id":327},"descripción-del-problema","Descripción del Problema",[304,330,331],{},"Supongamos que quieres crear un programa que simule la ejecución de varias tareas concurrentes, como la impresión de mensajes en la consola. Queremos que cada tarea se ejecute en un hilo separado y que el programa principal espere a que todas las tareas se completen antes de finalizar.",[325,333,335],{"id":334},"código-de-resolución","Código de Resolución",[304,337,338,339,342,343,345,346,349,350,352,353,355,356,359],{},"Para resolver este problema, crearemos una clase ",[308,340,341],{},"Task"," que implementa la interfaz ",[308,344,314],{},". Esta clase representará una tarea que se ejecutará en un hilo separado. Luego, crearemos una clase ",[308,347,348],{},"ThreadManager"," que manejará la creación y ejecución de los hilos para cada tarea. Posteriormente, utilizaremos las funciones ",[308,351,318],{}," para simular el tiempo de ejecución de cada tarea, ",[308,354,322],{}," para esperar a que los hilos terminen su ejecución y ",[308,357,358],{},"interrupt"," para manejar posibles interrupciones. Para finalizar, implementaremos un Función para mostrar el progreso de las tareas.",[361,362,364,365],"h3",{"id":363},"paso-1-crear-la-clase-task","Paso 1: Crear la clase ",[308,366,341],{},[368,369,374],"pre",{"className":370,"code":371,"language":372,"meta":373,"style":373},"language-java shiki shiki-themes github-dark","package app.concurrencia.entities;\n\n\u002F**\n * Clase que representa una tarea que se ejecutará en un hilo separado.\n *\u002F\npublic class Task implements Runnable {\n    \u002F**\n     * Nombre de la tarea.\n     *\u002F\n    private String taskName;\n\n    \u002F**\n     * Constructor de la clase Task.\n     * \n     * @param taskName Nombre de la tarea.\n     *\u002F\n    public Task(String taskName) {\n        this.taskName = taskName;\n    }\n\n    \u002F**\n     * Función que se ejecuta cuando el hilo inicia.\n     *\u002F\n    @Override\n    public void run() {\n        try {\n            for (int i = 0; i \u003C 5; i++) {\n                System.out.println(taskName + \" - Iteración \" + (i + 1));\n                Thread.sleep(1000); \u002F\u002F Simula el tiempo de ejecución de la tarea\n            }\n        } catch (InterruptedException e) {\n            System.out.println(taskName + \" ha sido interrumpida.\");\n        }\n    }\n}\n","java","",[308,375,376,389,396,403,409,415,437,443,449,455,464,469,474,480,486,502,507,524,540,546,551,556,562,567,576,590,598,635,668,688,694,711,729,735,740],{"__ignoreMap":373},[377,378,381,385],"span",{"class":379,"line":380},"line",1,[377,382,384],{"class":383},"snl16","package",[377,386,388],{"class":387},"s95oV"," app.concurrencia.entities;\n",[377,390,392],{"class":379,"line":391},2,[377,393,395],{"emptyLinePlaceholder":394},true,"\n",[377,397,399],{"class":379,"line":398},3,[377,400,402],{"class":401},"sAwPA","\u002F**\n",[377,404,406],{"class":379,"line":405},4,[377,407,408],{"class":401}," * Clase que representa una tarea que se ejecutará en un hilo separado.\n",[377,410,412],{"class":379,"line":411},5,[377,413,414],{"class":401}," *\u002F\n",[377,416,418,421,424,428,431,434],{"class":379,"line":417},6,[377,419,420],{"class":383},"public",[377,422,423],{"class":383}," class",[377,425,427],{"class":426},"svObZ"," Task",[377,429,430],{"class":383}," implements",[377,432,433],{"class":426}," Runnable",[377,435,436],{"class":387}," {\n",[377,438,440],{"class":379,"line":439},7,[377,441,442],{"class":401},"    \u002F**\n",[377,444,446],{"class":379,"line":445},8,[377,447,448],{"class":401},"     * Nombre de la tarea.\n",[377,450,452],{"class":379,"line":451},9,[377,453,454],{"class":401},"     *\u002F\n",[377,456,458,461],{"class":379,"line":457},10,[377,459,460],{"class":383},"    private",[377,462,463],{"class":387}," String taskName;\n",[377,465,467],{"class":379,"line":466},11,[377,468,395],{"emptyLinePlaceholder":394},[377,470,472],{"class":379,"line":471},12,[377,473,442],{"class":401},[377,475,477],{"class":379,"line":476},13,[377,478,479],{"class":401},"     * Constructor de la clase Task.\n",[377,481,483],{"class":379,"line":482},14,[377,484,485],{"class":401},"     * \n",[377,487,489,492,495,499],{"class":379,"line":488},15,[377,490,491],{"class":401},"     * ",[377,493,494],{"class":383},"@param",[377,496,498],{"class":497},"s9osk"," taskName",[377,500,501],{"class":401}," Nombre de la tarea.\n",[377,503,505],{"class":379,"line":504},16,[377,506,454],{"class":401},[377,508,510,513,515,518,521],{"class":379,"line":509},17,[377,511,512],{"class":383},"    public",[377,514,427],{"class":426},[377,516,517],{"class":387},"(String ",[377,519,520],{"class":497},"taskName",[377,522,523],{"class":387},") {\n",[377,525,527,531,534,537],{"class":379,"line":526},18,[377,528,530],{"class":529},"sDLfK","        this",[377,532,533],{"class":387},".taskName ",[377,535,536],{"class":383},"=",[377,538,539],{"class":387}," taskName;\n",[377,541,543],{"class":379,"line":542},19,[377,544,545],{"class":387},"    }\n",[377,547,549],{"class":379,"line":548},20,[377,550,395],{"emptyLinePlaceholder":394},[377,552,554],{"class":379,"line":553},21,[377,555,442],{"class":401},[377,557,559],{"class":379,"line":558},22,[377,560,561],{"class":401},"     * Función que se ejecuta cuando el hilo inicia.\n",[377,563,565],{"class":379,"line":564},23,[377,566,454],{"class":401},[377,568,570,573],{"class":379,"line":569},24,[377,571,572],{"class":387},"    @",[377,574,575],{"class":383},"Override\n",[377,577,579,581,584,587],{"class":379,"line":578},25,[377,580,512],{"class":383},[377,582,583],{"class":383}," void",[377,585,586],{"class":426}," run",[377,588,589],{"class":387},"() {\n",[377,591,593,596],{"class":379,"line":592},26,[377,594,595],{"class":383},"        try",[377,597,436],{"class":387},[377,599,601,604,607,610,613,615,618,621,624,627,630,633],{"class":379,"line":600},27,[377,602,603],{"class":383},"            for",[377,605,606],{"class":387}," (",[377,608,609],{"class":383},"int",[377,611,612],{"class":387}," i ",[377,614,536],{"class":383},[377,616,617],{"class":529}," 0",[377,619,620],{"class":387},"; i ",[377,622,623],{"class":383},"\u003C",[377,625,626],{"class":529}," 5",[377,628,629],{"class":387},"; i",[377,631,632],{"class":383},"++",[377,634,523],{"class":387},[377,636,638,641,644,647,650,654,657,660,662,665],{"class":379,"line":637},28,[377,639,640],{"class":387},"                System.out.",[377,642,643],{"class":426},"println",[377,645,646],{"class":387},"(taskName ",[377,648,649],{"class":383},"+",[377,651,653],{"class":652},"sU2Wk"," \" - Iteración \"",[377,655,656],{"class":383}," +",[377,658,659],{"class":387}," (i ",[377,661,649],{"class":383},[377,663,664],{"class":529}," 1",[377,666,667],{"class":387},"));\n",[377,669,671,674,676,679,682,685],{"class":379,"line":670},29,[377,672,673],{"class":387},"                Thread.",[377,675,318],{"class":426},[377,677,678],{"class":387},"(",[377,680,681],{"class":529},"1000",[377,683,684],{"class":387},"); ",[377,686,687],{"class":401},"\u002F\u002F Simula el tiempo de ejecución de la tarea\n",[377,689,691],{"class":379,"line":690},30,[377,692,693],{"class":387},"            }\n",[377,695,697,700,703,706,709],{"class":379,"line":696},31,[377,698,699],{"class":387},"        } ",[377,701,702],{"class":383},"catch",[377,704,705],{"class":387}," (InterruptedException ",[377,707,708],{"class":497},"e",[377,710,523],{"class":387},[377,712,714,717,719,721,723,726],{"class":379,"line":713},32,[377,715,716],{"class":387},"            System.out.",[377,718,643],{"class":426},[377,720,646],{"class":387},[377,722,649],{"class":383},[377,724,725],{"class":652}," \" ha sido interrumpida.\"",[377,727,728],{"class":387},");\n",[377,730,732],{"class":379,"line":731},33,[377,733,734],{"class":387},"        }\n",[377,736,738],{"class":379,"line":737},34,[377,739,545],{"class":387},[377,741,743],{"class":379,"line":742},35,[377,744,745],{"class":387},"}\n",[361,747,749,750],{"id":748},"paso-2-crear-la-clase-threadmanager","Paso 2: Crear la clase ",[308,751,348],{},[368,753,755],{"className":370,"code":754,"language":372,"meta":373,"style":373},"package app.concurrencia.entities;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\u002F**\n * Clase que maneja la creación y ejecución de hilos para cada tarea.\n *\u002F\npublic class ThreadManager {\n    private List\u003CThread> threads;\n\n    public ThreadManager() {\n        threads = new ArrayList\u003C>();\n    }\n\n    \u002F**\n     * Función para iniciar las tareas en hilos separados.\n     * \n     * @param tasks Lista de tareas a ejecutar.\n     *\u002F\n    public void startTasks(List\u003CTask> tasks) {\n        for (Task task : tasks) {\n            Thread thread = new Thread(task);\n            threads.add(thread);\n            thread.start();\n        }\n    }\n\n    \u002F**\n     * Función para esperar a que todas las tareas se completen.\n     *\u002F\n    public void waitForTasks() {\n        for (Thread thread : threads) {\n            try {\n                thread.join(); \u002F\u002F Espera a que el hilo termine su ejecución\n            } catch (InterruptedException e) {\n                System.out.println(\"El hilo ha sido interrumpido.\");\n            }\n        }\n    }\n\n    \u002F**\n     * Función para interrumpir todas las tareas.\n     *\u002F\n    public void interruptTasks() {\n        for (Thread thread : threads) {\n            thread.interrupt(); \u002F\u002F Interrumpe el hilo\n        }\n    }\n\n    \u002F**\n     * Función para mostrar el progreso de las tareas.\n     *\u002F\n    public void showProgress() {\n        for (Thread thread : threads) {\n            if (thread.isAlive()) {\n                System.out.println(thread.getName() + \" está en ejecución.\");\n            } else {\n                System.out.println(thread.getName() + \" ha finalizado.\");\n            }\n        }\n    }\n}\n",[308,756,757,763,767,775,782,786,790,795,799,810,822,826,834,847,851,855,859,864,868,880,884,906,920,935,946,957,961,965,969,973,978,982,993,1005,1012,1025,1039,1053,1058,1063,1068,1073,1078,1084,1089,1101,1112,1124,1129,1134,1139,1144,1150,1155,1167,1178,1193,1216,1226,1246,1251,1256,1261],{"__ignoreMap":373},[377,758,759,761],{"class":379,"line":380},[377,760,384],{"class":383},[377,762,388],{"class":387},[377,764,765],{"class":379,"line":391},[377,766,395],{"emptyLinePlaceholder":394},[377,768,769,772],{"class":379,"line":398},[377,770,771],{"class":383},"import",[377,773,774],{"class":387}," java.util.ArrayList;\n",[377,776,777,779],{"class":379,"line":405},[377,778,771],{"class":383},[377,780,781],{"class":387}," java.util.List;\n",[377,783,784],{"class":379,"line":411},[377,785,395],{"emptyLinePlaceholder":394},[377,787,788],{"class":379,"line":417},[377,789,402],{"class":401},[377,791,792],{"class":379,"line":439},[377,793,794],{"class":401}," * Clase que maneja la creación y ejecución de hilos para cada tarea.\n",[377,796,797],{"class":379,"line":445},[377,798,414],{"class":401},[377,800,801,803,805,808],{"class":379,"line":451},[377,802,420],{"class":383},[377,804,423],{"class":383},[377,806,807],{"class":426}," ThreadManager",[377,809,436],{"class":387},[377,811,812,814,817,819],{"class":379,"line":457},[377,813,460],{"class":383},[377,815,816],{"class":387}," List\u003C",[377,818,310],{"class":383},[377,820,821],{"class":387},"> threads;\n",[377,823,824],{"class":379,"line":466},[377,825,395],{"emptyLinePlaceholder":394},[377,827,828,830,832],{"class":379,"line":471},[377,829,512],{"class":383},[377,831,807],{"class":426},[377,833,589],{"class":387},[377,835,836,839,841,844],{"class":379,"line":476},[377,837,838],{"class":387},"        threads ",[377,840,536],{"class":383},[377,842,843],{"class":383}," new",[377,845,846],{"class":387}," ArrayList\u003C>();\n",[377,848,849],{"class":379,"line":482},[377,850,545],{"class":387},[377,852,853],{"class":379,"line":488},[377,854,395],{"emptyLinePlaceholder":394},[377,856,857],{"class":379,"line":504},[377,858,442],{"class":401},[377,860,861],{"class":379,"line":509},[377,862,863],{"class":401},"     * Función para iniciar las tareas en hilos separados.\n",[377,865,866],{"class":379,"line":526},[377,867,485],{"class":401},[377,869,870,872,874,877],{"class":379,"line":542},[377,871,491],{"class":401},[377,873,494],{"class":383},[377,875,876],{"class":497}," tasks",[377,878,879],{"class":401}," Lista de tareas a ejecutar.\n",[377,881,882],{"class":379,"line":548},[377,883,454],{"class":401},[377,885,886,888,890,893,896,898,901,904],{"class":379,"line":553},[377,887,512],{"class":383},[377,889,583],{"class":383},[377,891,892],{"class":426}," startTasks",[377,894,895],{"class":387},"(List\u003C",[377,897,341],{"class":383},[377,899,900],{"class":387},"> ",[377,902,903],{"class":497},"tasks",[377,905,523],{"class":387},[377,907,908,911,914,917],{"class":379,"line":558},[377,909,910],{"class":383},"        for",[377,912,913],{"class":387}," (Task task ",[377,915,916],{"class":383},":",[377,918,919],{"class":387}," tasks) {\n",[377,921,922,925,927,929,932],{"class":379,"line":564},[377,923,924],{"class":387},"            Thread thread ",[377,926,536],{"class":383},[377,928,843],{"class":383},[377,930,931],{"class":426}," Thread",[377,933,934],{"class":387},"(task);\n",[377,936,937,940,943],{"class":379,"line":569},[377,938,939],{"class":387},"            threads.",[377,941,942],{"class":426},"add",[377,944,945],{"class":387},"(thread);\n",[377,947,948,951,954],{"class":379,"line":578},[377,949,950],{"class":387},"            thread.",[377,952,953],{"class":426},"start",[377,955,956],{"class":387},"();\n",[377,958,959],{"class":379,"line":592},[377,960,734],{"class":387},[377,962,963],{"class":379,"line":600},[377,964,545],{"class":387},[377,966,967],{"class":379,"line":637},[377,968,395],{"emptyLinePlaceholder":394},[377,970,971],{"class":379,"line":670},[377,972,442],{"class":401},[377,974,975],{"class":379,"line":690},[377,976,977],{"class":401},"     * Función para esperar a que todas las tareas se completen.\n",[377,979,980],{"class":379,"line":696},[377,981,454],{"class":401},[377,983,984,986,988,991],{"class":379,"line":713},[377,985,512],{"class":383},[377,987,583],{"class":383},[377,989,990],{"class":426}," waitForTasks",[377,992,589],{"class":387},[377,994,995,997,1000,1002],{"class":379,"line":731},[377,996,910],{"class":383},[377,998,999],{"class":387}," (Thread thread ",[377,1001,916],{"class":383},[377,1003,1004],{"class":387}," threads) {\n",[377,1006,1007,1010],{"class":379,"line":737},[377,1008,1009],{"class":383},"            try",[377,1011,436],{"class":387},[377,1013,1014,1017,1019,1022],{"class":379,"line":742},[377,1015,1016],{"class":387},"                thread.",[377,1018,322],{"class":426},[377,1020,1021],{"class":387},"(); ",[377,1023,1024],{"class":401},"\u002F\u002F Espera a que el hilo termine su ejecución\n",[377,1026,1028,1031,1033,1035,1037],{"class":379,"line":1027},36,[377,1029,1030],{"class":387},"            } ",[377,1032,702],{"class":383},[377,1034,705],{"class":387},[377,1036,708],{"class":497},[377,1038,523],{"class":387},[377,1040,1042,1044,1046,1048,1051],{"class":379,"line":1041},37,[377,1043,640],{"class":387},[377,1045,643],{"class":426},[377,1047,678],{"class":387},[377,1049,1050],{"class":652},"\"El hilo ha sido interrumpido.\"",[377,1052,728],{"class":387},[377,1054,1056],{"class":379,"line":1055},38,[377,1057,693],{"class":387},[377,1059,1061],{"class":379,"line":1060},39,[377,1062,734],{"class":387},[377,1064,1066],{"class":379,"line":1065},40,[377,1067,545],{"class":387},[377,1069,1071],{"class":379,"line":1070},41,[377,1072,395],{"emptyLinePlaceholder":394},[377,1074,1076],{"class":379,"line":1075},42,[377,1077,442],{"class":401},[377,1079,1081],{"class":379,"line":1080},43,[377,1082,1083],{"class":401},"     * Función para interrumpir todas las tareas.\n",[377,1085,1087],{"class":379,"line":1086},44,[377,1088,454],{"class":401},[377,1090,1092,1094,1096,1099],{"class":379,"line":1091},45,[377,1093,512],{"class":383},[377,1095,583],{"class":383},[377,1097,1098],{"class":426}," interruptTasks",[377,1100,589],{"class":387},[377,1102,1104,1106,1108,1110],{"class":379,"line":1103},46,[377,1105,910],{"class":383},[377,1107,999],{"class":387},[377,1109,916],{"class":383},[377,1111,1004],{"class":387},[377,1113,1115,1117,1119,1121],{"class":379,"line":1114},47,[377,1116,950],{"class":387},[377,1118,358],{"class":426},[377,1120,1021],{"class":387},[377,1122,1123],{"class":401},"\u002F\u002F Interrumpe el hilo\n",[377,1125,1127],{"class":379,"line":1126},48,[377,1128,734],{"class":387},[377,1130,1132],{"class":379,"line":1131},49,[377,1133,545],{"class":387},[377,1135,1137],{"class":379,"line":1136},50,[377,1138,395],{"emptyLinePlaceholder":394},[377,1140,1142],{"class":379,"line":1141},51,[377,1143,442],{"class":401},[377,1145,1147],{"class":379,"line":1146},52,[377,1148,1149],{"class":401},"     * Función para mostrar el progreso de las tareas.\n",[377,1151,1153],{"class":379,"line":1152},53,[377,1154,454],{"class":401},[377,1156,1158,1160,1162,1165],{"class":379,"line":1157},54,[377,1159,512],{"class":383},[377,1161,583],{"class":383},[377,1163,1164],{"class":426}," showProgress",[377,1166,589],{"class":387},[377,1168,1170,1172,1174,1176],{"class":379,"line":1169},55,[377,1171,910],{"class":383},[377,1173,999],{"class":387},[377,1175,916],{"class":383},[377,1177,1004],{"class":387},[377,1179,1181,1184,1187,1190],{"class":379,"line":1180},56,[377,1182,1183],{"class":383},"            if",[377,1185,1186],{"class":387}," (thread.",[377,1188,1189],{"class":426},"isAlive",[377,1191,1192],{"class":387},"()) {\n",[377,1194,1196,1198,1200,1203,1206,1209,1211,1214],{"class":379,"line":1195},57,[377,1197,640],{"class":387},[377,1199,643],{"class":426},[377,1201,1202],{"class":387},"(thread.",[377,1204,1205],{"class":426},"getName",[377,1207,1208],{"class":387},"() ",[377,1210,649],{"class":383},[377,1212,1213],{"class":652}," \" está en ejecución.\"",[377,1215,728],{"class":387},[377,1217,1219,1221,1224],{"class":379,"line":1218},58,[377,1220,1030],{"class":387},[377,1222,1223],{"class":383},"else",[377,1225,436],{"class":387},[377,1227,1229,1231,1233,1235,1237,1239,1241,1244],{"class":379,"line":1228},59,[377,1230,640],{"class":387},[377,1232,643],{"class":426},[377,1234,1202],{"class":387},[377,1236,1205],{"class":426},[377,1238,1208],{"class":387},[377,1240,649],{"class":383},[377,1242,1243],{"class":652}," \" ha finalizado.\"",[377,1245,728],{"class":387},[377,1247,1249],{"class":379,"line":1248},60,[377,1250,693],{"class":387},[377,1252,1254],{"class":379,"line":1253},61,[377,1255,734],{"class":387},[377,1257,1259],{"class":379,"line":1258},62,[377,1260,545],{"class":387},[377,1262,1264],{"class":379,"line":1263},63,[377,1265,745],{"class":387},[361,1267,1269,1270],{"id":1268},"paso-3-crear-la-clase-main","Paso 3: Crear la clase ",[308,1271,1272],{},"Main",[368,1274,1276],{"className":370,"code":1275,"language":372,"meta":373,"style":373},"package app.concurrencia.launch;\n\nimport app.concurrencia.entities.Task;\nimport app.concurrencia.entities.ThreadManager;\nimport java.util.Arrays;\n\npublic class Main {\n    void main() {\n        ThreadManager threadManager = new ThreadManager();\n\n        \u002F\u002F Crear una lista de tareas\n        Task task1 = new Task(\"Tarea 1\");\n        Task task2 = new Task(\"Tarea 2\");\n        Task task3 = new Task(\"Tarea 3\");\n\n        \u002F\u002F Iniciar las tareas en hilos separados\n        threadManager.startTasks(Arrays.asList(task1, task2, task3));\n\n        \u002F\u002F Mostrar el progreso de las tareas\n        threadManager.showProgress();\n\n        \u002F\u002F Esperar a que todas las tareas se completen\n        threadManager.waitForTasks();\n\n        \u002F\u002F Mostrar el progreso final de las tareas\n        threadManager.showProgress();\n    }\n}\n",[308,1277,1278,1285,1289,1296,1303,1310,1314,1325,1335,1348,1352,1357,1375,1393,1411,1415,1420,1437,1441,1446,1455,1459,1464,1473,1477,1482,1490,1494],{"__ignoreMap":373},[377,1279,1280,1282],{"class":379,"line":380},[377,1281,384],{"class":383},[377,1283,1284],{"class":387}," app.concurrencia.launch;\n",[377,1286,1287],{"class":379,"line":391},[377,1288,395],{"emptyLinePlaceholder":394},[377,1290,1291,1293],{"class":379,"line":398},[377,1292,771],{"class":383},[377,1294,1295],{"class":387}," app.concurrencia.entities.Task;\n",[377,1297,1298,1300],{"class":379,"line":405},[377,1299,771],{"class":383},[377,1301,1302],{"class":387}," app.concurrencia.entities.ThreadManager;\n",[377,1304,1305,1307],{"class":379,"line":411},[377,1306,771],{"class":383},[377,1308,1309],{"class":387}," java.util.Arrays;\n",[377,1311,1312],{"class":379,"line":417},[377,1313,395],{"emptyLinePlaceholder":394},[377,1315,1316,1318,1320,1323],{"class":379,"line":439},[377,1317,420],{"class":383},[377,1319,423],{"class":383},[377,1321,1322],{"class":426}," Main",[377,1324,436],{"class":387},[377,1326,1327,1330,1333],{"class":379,"line":445},[377,1328,1329],{"class":383},"    void",[377,1331,1332],{"class":426}," main",[377,1334,589],{"class":387},[377,1336,1337,1340,1342,1344,1346],{"class":379,"line":451},[377,1338,1339],{"class":387},"        ThreadManager threadManager ",[377,1341,536],{"class":383},[377,1343,843],{"class":383},[377,1345,807],{"class":426},[377,1347,956],{"class":387},[377,1349,1350],{"class":379,"line":457},[377,1351,395],{"emptyLinePlaceholder":394},[377,1353,1354],{"class":379,"line":466},[377,1355,1356],{"class":401},"        \u002F\u002F Crear una lista de tareas\n",[377,1358,1359,1362,1364,1366,1368,1370,1373],{"class":379,"line":471},[377,1360,1361],{"class":387},"        Task task1 ",[377,1363,536],{"class":383},[377,1365,843],{"class":383},[377,1367,427],{"class":426},[377,1369,678],{"class":387},[377,1371,1372],{"class":652},"\"Tarea 1\"",[377,1374,728],{"class":387},[377,1376,1377,1380,1382,1384,1386,1388,1391],{"class":379,"line":476},[377,1378,1379],{"class":387},"        Task task2 ",[377,1381,536],{"class":383},[377,1383,843],{"class":383},[377,1385,427],{"class":426},[377,1387,678],{"class":387},[377,1389,1390],{"class":652},"\"Tarea 2\"",[377,1392,728],{"class":387},[377,1394,1395,1398,1400,1402,1404,1406,1409],{"class":379,"line":482},[377,1396,1397],{"class":387},"        Task task3 ",[377,1399,536],{"class":383},[377,1401,843],{"class":383},[377,1403,427],{"class":426},[377,1405,678],{"class":387},[377,1407,1408],{"class":652},"\"Tarea 3\"",[377,1410,728],{"class":387},[377,1412,1413],{"class":379,"line":488},[377,1414,395],{"emptyLinePlaceholder":394},[377,1416,1417],{"class":379,"line":504},[377,1418,1419],{"class":401},"        \u002F\u002F Iniciar las tareas en hilos separados\n",[377,1421,1422,1425,1428,1431,1434],{"class":379,"line":509},[377,1423,1424],{"class":387},"        threadManager.",[377,1426,1427],{"class":426},"startTasks",[377,1429,1430],{"class":387},"(Arrays.",[377,1432,1433],{"class":426},"asList",[377,1435,1436],{"class":387},"(task1, task2, task3));\n",[377,1438,1439],{"class":379,"line":526},[377,1440,395],{"emptyLinePlaceholder":394},[377,1442,1443],{"class":379,"line":542},[377,1444,1445],{"class":401},"        \u002F\u002F Mostrar el progreso de las tareas\n",[377,1447,1448,1450,1453],{"class":379,"line":548},[377,1449,1424],{"class":387},[377,1451,1452],{"class":426},"showProgress",[377,1454,956],{"class":387},[377,1456,1457],{"class":379,"line":553},[377,1458,395],{"emptyLinePlaceholder":394},[377,1460,1461],{"class":379,"line":558},[377,1462,1463],{"class":401},"        \u002F\u002F Esperar a que todas las tareas se completen\n",[377,1465,1466,1468,1471],{"class":379,"line":564},[377,1467,1424],{"class":387},[377,1469,1470],{"class":426},"waitForTasks",[377,1472,956],{"class":387},[377,1474,1475],{"class":379,"line":569},[377,1476,395],{"emptyLinePlaceholder":394},[377,1478,1479],{"class":379,"line":578},[377,1480,1481],{"class":401},"        \u002F\u002F Mostrar el progreso final de las tareas\n",[377,1483,1484,1486,1488],{"class":379,"line":592},[377,1485,1424],{"class":387},[377,1487,1452],{"class":426},[377,1489,956],{"class":387},[377,1491,1492],{"class":379,"line":600},[377,1493,545],{"class":387},[377,1495,1496],{"class":379,"line":637},[377,1497,745],{"class":387},[325,1499,1501],{"id":1500},"salida-esperada","Salida Esperada",[304,1503,1504],{},"Cuando ejecutes el programa, deberías ver una salida similar a la siguiente en la consola:",[368,1506,1511],{"className":1507,"code":1509,"language":1510},[1508],"language-text","Tarea 1 - Iteración 1\nTarea 2 - Iteración 1\nTarea 3 - Iteración 1\nTarea 1 - Iteración 2\nTarea 2 - Iteración 2\nTarea 3 - Iteración 2\nTarea 1 - Iteración 3\nTarea 2 - Iteración 3\nTarea 3 - Iteración 3\nTarea 1 - Iteración 4\nTarea 2 - Iteración 4\nTarea 3 - Iteración 4\nTarea 1 - Iteración 5\nTarea 2 - Iteración 5\nTarea 3 - Iteración 5\nTarea 1 ha finalizado.\nTarea 2 ha finalizado.\nTarea 3 ha finalizado.\n","text",[308,1512,1509],{"__ignoreMap":373},[304,1514,1515],{},"En esta salida, cada tarea se ejecuta en un hilo separado, y el programa principal espera a que todas las tareas se completen antes de finalizar. Además, se muestra el progreso de las tareas antes y después de la ejecución.",[325,1517,1519],{"id":1518},"terminar-las-tareas-por-interrupción","Terminar las tareas por interrupción",[304,1521,1522,1523,1526,1527,1529],{},"Si deseas terminar las tareas antes de que completen su ejecución, puedes llamar a la función ",[308,1524,1525],{},"interruptTasks()"," del ",[308,1528,348],{},". Esto interrumpirá todos los hilos en ejecución, y cada tarea manejará la interrupción mostrando un mensaje en la consola.",[368,1531,1533],{"className":370,"code":1532,"language":372,"meta":373,"style":373},"\u002F\u002F Interrumpir todas las tareas\nthreadManager.interruptTasks();\n",[308,1534,1535,1540],{"__ignoreMap":373},[377,1536,1537],{"class":379,"line":380},[377,1538,1539],{"class":401},"\u002F\u002F Interrumpir todas las tareas\n",[377,1541,1542,1545,1548],{"class":379,"line":391},[377,1543,1544],{"class":387},"threadManager.",[377,1546,1547],{"class":426},"interruptTasks",[377,1549,956],{"class":387},[304,1551,1552],{},"Al ejecutar esta línea, verás mensajes similares a los siguientes en la consola:",[368,1554,1557],{"className":1555,"code":1556,"language":1510},[1508],"Tarea 1 ha sido interrumpida.\nTarea 2 ha sido interrumpida.\nTarea 3 ha sido interrumpida.\n",[308,1558,1556],{"__ignoreMap":373},[325,1560,1562],{"id":1561},"terminando-las-tareas-por-ráfagas","Terminando las tareas por ráfagas",[304,1564,1565,1566,1568],{},"Recordemos que la función ",[308,1567,322],{}," cuenta con una sobrecarga que permite especificar un tiempo máximo de espera para que un hilo termine su ejecución. Si el hilo no termina dentro de ese tiempo, el programa continúa con la siguiente línea de código. Esto es útil para evitar que el programa se quede bloqueado esperando a que un hilo termine su ejecución.",[304,1570,1571],{},"Entonces, usemos esto para esperar a que las tareas terminen su ejecución por ráfagas, es decir, esperando un tiempo máximo para cada tarea antes de continuar con la siguiente tarea, interrumpiendo las tareas que no hayan terminado dentro de ese tiempo máximo y agregando nuevamente la tarea a la lista de tareas para esperar nuevamente en la siguiente ráfaga.",[304,1573,1574,1575,1526,1577,1579],{},"Para esto, modificaremos la función ",[308,1576,1470],{},[308,1578,348],{}," de la siguiente manera:",[368,1581,1583],{"className":370,"code":1582,"language":372,"meta":373,"style":373},"public void waitForTasks(int maxWaitTime) {\n    List\u003CThread> remainingThreads = new ArrayList\u003C>(threads);\n    while (!remainingThreads.isEmpty()) {\n        List\u003CThread> threadsToRemove = new ArrayList\u003C>();\n        for (Thread thread : remainingThreads) {\n            try {\n                thread.join(maxWaitTime); \u002F\u002F Espera un tiempo máximo para que el hilo termine su ejecución\n                if (!thread.isAlive()) {\n                    threadsToRemove.add(thread); \u002F\u002F Si el hilo ha terminado, lo agregamos a la lista de hilos a eliminar\n                } else {\n                    thread.interrupt(); \u002F\u002F Si el hilo no ha terminado, lo interrumpimos\n                }\n            } catch (InterruptedException e) {\n                System.out.println(\"El hilo ha sido interrumpido.\");\n            }\n        }\n        remainingThreads.removeAll(threadsToRemove); \u002F\u002F Eliminamos los hilos que han terminado de la lista de hilos restantes\n    }\n}\n",[308,1584,1585,1600,1617,1635,1651,1662,1668,1680,1696,1709,1718,1730,1735,1747,1759,1763,1767,1781,1785],{"__ignoreMap":373},[377,1586,1587,1589,1591,1593,1595,1597],{"class":379,"line":380},[377,1588,420],{"class":383},[377,1590,583],{"class":383},[377,1592,990],{"class":426},[377,1594,678],{"class":387},[377,1596,609],{"class":383},[377,1598,1599],{"class":387}," maxWaitTime) {\n",[377,1601,1602,1605,1607,1610,1612,1614],{"class":379,"line":391},[377,1603,1604],{"class":387},"    List\u003C",[377,1606,310],{"class":383},[377,1608,1609],{"class":387},"> remainingThreads ",[377,1611,536],{"class":383},[377,1613,843],{"class":383},[377,1615,1616],{"class":387}," ArrayList\u003C>(threads);\n",[377,1618,1619,1622,1624,1627,1630,1633],{"class":379,"line":398},[377,1620,1621],{"class":383},"    while",[377,1623,606],{"class":387},[377,1625,1626],{"class":383},"!",[377,1628,1629],{"class":387},"remainingThreads.",[377,1631,1632],{"class":426},"isEmpty",[377,1634,1192],{"class":387},[377,1636,1637,1640,1642,1645,1647,1649],{"class":379,"line":405},[377,1638,1639],{"class":387},"        List\u003C",[377,1641,310],{"class":383},[377,1643,1644],{"class":387},"> threadsToRemove ",[377,1646,536],{"class":383},[377,1648,843],{"class":383},[377,1650,846],{"class":387},[377,1652,1653,1655,1657,1659],{"class":379,"line":411},[377,1654,910],{"class":383},[377,1656,999],{"class":387},[377,1658,916],{"class":383},[377,1660,1661],{"class":387}," remainingThreads) {\n",[377,1663,1664,1666],{"class":379,"line":417},[377,1665,1009],{"class":383},[377,1667,436],{"class":387},[377,1669,1670,1672,1674,1677],{"class":379,"line":439},[377,1671,1016],{"class":387},[377,1673,322],{"class":426},[377,1675,1676],{"class":387},"(maxWaitTime); ",[377,1678,1679],{"class":401},"\u002F\u002F Espera un tiempo máximo para que el hilo termine su ejecución\n",[377,1681,1682,1685,1687,1689,1692,1694],{"class":379,"line":445},[377,1683,1684],{"class":383},"                if",[377,1686,606],{"class":387},[377,1688,1626],{"class":383},[377,1690,1691],{"class":387},"thread.",[377,1693,1189],{"class":426},[377,1695,1192],{"class":387},[377,1697,1698,1701,1703,1706],{"class":379,"line":451},[377,1699,1700],{"class":387},"                    threadsToRemove.",[377,1702,942],{"class":426},[377,1704,1705],{"class":387},"(thread); ",[377,1707,1708],{"class":401},"\u002F\u002F Si el hilo ha terminado, lo agregamos a la lista de hilos a eliminar\n",[377,1710,1711,1714,1716],{"class":379,"line":457},[377,1712,1713],{"class":387},"                } ",[377,1715,1223],{"class":383},[377,1717,436],{"class":387},[377,1719,1720,1723,1725,1727],{"class":379,"line":466},[377,1721,1722],{"class":387},"                    thread.",[377,1724,358],{"class":426},[377,1726,1021],{"class":387},[377,1728,1729],{"class":401},"\u002F\u002F Si el hilo no ha terminado, lo interrumpimos\n",[377,1731,1732],{"class":379,"line":471},[377,1733,1734],{"class":387},"                }\n",[377,1736,1737,1739,1741,1743,1745],{"class":379,"line":476},[377,1738,1030],{"class":387},[377,1740,702],{"class":383},[377,1742,705],{"class":387},[377,1744,708],{"class":497},[377,1746,523],{"class":387},[377,1748,1749,1751,1753,1755,1757],{"class":379,"line":482},[377,1750,640],{"class":387},[377,1752,643],{"class":426},[377,1754,678],{"class":387},[377,1756,1050],{"class":652},[377,1758,728],{"class":387},[377,1760,1761],{"class":379,"line":488},[377,1762,693],{"class":387},[377,1764,1765],{"class":379,"line":504},[377,1766,734],{"class":387},[377,1768,1769,1772,1775,1778],{"class":379,"line":509},[377,1770,1771],{"class":387},"        remainingThreads.",[377,1773,1774],{"class":426},"removeAll",[377,1776,1777],{"class":387},"(threadsToRemove); ",[377,1779,1780],{"class":401},"\u002F\u002F Eliminamos los hilos que han terminado de la lista de hilos restantes\n",[377,1782,1783],{"class":379,"line":526},[377,1784,545],{"class":387},[377,1786,1787],{"class":379,"line":542},[377,1788,745],{"class":387},[304,1790,1791,1792,1795,1796,1798,1799,1801],{},"En esta función, se espera un tiempo máximo para cada hilo antes de continuar con la siguiente tarea. Si un hilo no termina dentro de ese tiempo, se interrumpe y se agrega nuevamente a la lista de tareas para esperar nuevamente en la siguiente ráfaga. Este proceso se repite hasta que todas las tareas hayan terminado su ejecución. Para que esto funcione, también debemos modificar la función ",[308,1793,1794],{},"main"," de la clase ",[308,1797,1272],{}," para llamar a esta nueva función ",[308,1800,1470],{}," con un tiempo máximo de espera, por ejemplo, 2000 milisegundos:",[368,1803,1805],{"className":370,"code":1804,"language":372,"meta":373,"style":373},"\u002F\u002F Esperar a que todas las tareas se completen por ráfagas\nthreadManager.waitForTasks(2000);\n",[308,1806,1807,1812],{"__ignoreMap":373},[377,1808,1809],{"class":379,"line":380},[377,1810,1811],{"class":401},"\u002F\u002F Esperar a que todas las tareas se completen por ráfagas\n",[377,1813,1814,1816,1818,1820,1823],{"class":379,"line":391},[377,1815,1544],{"class":387},[377,1817,1470],{"class":426},[377,1819,678],{"class":387},[377,1821,1822],{"class":529},"2000",[377,1824,728],{"class":387},[304,1826,1827],{},"Con esta implementación, el programa esperará a que cada tarea termine su ejecución por ráfagas, interrumpiendo las tareas que no hayan terminado dentro del tiempo máximo de espera y continuando con la siguiente tarea. Esto permite un manejo más eficiente de las tareas concurrentes, evitando que el programa se quede bloqueado esperando a que una tarea termine su ejecución.",[325,1829,1831],{"id":1830},"conclusión","Conclusión",[304,1833,1834,1835,311,1837,315,1839,319,1841,1843],{},"En este ejemplo, hemos explorado diferentes formas de manejar hilos en Java, incluyendo la creación de hilos utilizando la clase ",[308,1836,310],{},[308,1838,314],{},[308,1840,318],{},[308,1842,322],{}," e interrupciones para controlar la ejecución de los hilos. Hemos visto cómo crear tareas que se ejecutan en hilos separados, cómo esperar a que las tareas terminen su ejecución por ráfagas y cómo interrumpir las tareas de manera adecuada. Este enfoque nos permite manejar eficientemente las tareas concurrentes en Java, evitando bloqueos y permitiendo un control más preciso sobre la ejecución de los hilos.",[1845,1846,1847],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":373,"searchDepth":391,"depth":391,"links":1849},[1850,1851,1859,1860,1861,1862],{"id":327,"depth":391,"text":328},{"id":334,"depth":391,"text":335,"children":1852},[1853,1855,1857],{"id":363,"depth":398,"text":1854},"Paso 1: Crear la clase Task",{"id":748,"depth":398,"text":1856},"Paso 2: Crear la clase ThreadManager",{"id":1268,"depth":398,"text":1858},"Paso 3: Crear la clase Main",{"id":1500,"depth":391,"text":1501},{"id":1518,"depth":391,"text":1519},{"id":1561,"depth":391,"text":1562},{"id":1830,"depth":391,"text":1831},"En este ejemplo, exploraremos diferentes formas de manejar hilos en Java, incluyendo la creación de hilos utilizando la clase `Thread`, la interfaz `Runnable`, y el uso de las funciones `sleep`, `join` e interrupciones para controlar la ejecución de los hilos.","md",null,{"editButton":104},{"icon":83},{"title":238,"description":1863},"6VqUXJ22o6PcdEzCfsr_QQrRE-iQN0bCz8npDRshhWA",[1871,1873],{"title":234,"path":235,"stem":236,"description":1872,"icon":83,"children":-1},"Ejemplo de cómo usar hilos en Java usando Thread y Runnable, además de las funciones sleep y join e interrupciones.",{"title":242,"path":243,"stem":244,"description":1874,"icon":83,"children":-1},"En este artículo recrearemos una condición de carrera en Java utilizando un ejemplo práctico para ilustrar el concepto y las consecuencias de las condiciones de carrera en la programación concurrente.",1775101376001]