[{"data":1,"prerenderedAt":1401},["ShallowReactive",2],{"navigation_docs":3,"-ejemplos-ejemplo-05":298,"-ejemplos-ejemplo-05-surround":1396},[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":234,"body":300,"description":1389,"extension":1390,"links":1391,"meta":1392,"navigation":1393,"path":235,"seo":1394,"stem":236,"__hash__":1395},"docs\u002F7.ejemplos\u002F05.ejemplo-05.md",{"type":301,"value":302,"toc":1376},"minimark",[303,324,329,332,352,356,359,362,372,379,392,747,754,760,1120,1127,1136,1336,1340,1343,1349,1352,1356,1372],[304,305,306,307,311,312,315,316,319,320,323],"p",{},"En este ejemplo, vamos a crear un programa en Java que utiliza hilos para ejecutar tareas concurrentes. Utilizaremos la clase ",[308,309,310],"code",{},"Thread"," y la interfaz ",[308,313,314],{},"Runnable"," para crear y manejar los hilos. Además, veremos cómo usar 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 queremos simular un proceso de descarga de archivos. Cada archivo se descargará en un hilo separado, y queremos que el programa principal espere a que todas las descargas se completen antes de finalizar.",[304,333,334,335,338,339,341,342,344,345,347,348,351],{},"Para resolver este problema, crearemos una clase ",[308,336,337],{},"DownloadTask"," que implementa la interfaz ",[308,340,314],{},". Esta clase representará la tarea de descargar un archivo. Luego, crearemos una clase que manejará la creación y ejecución de los hilos para cada tarea de descarga. Posteriormente, utilizaremos las funciones ",[308,343,318],{}," para simular el tiempo de descarga, ",[308,346,322],{}," para esperar a que los hilos terminen su ejecución y ",[308,349,350],{},"interrupt"," para manejar posibles interrupciones. Para finalizar, implementaremos un método para mostrar el progreso de las descargas.",[325,353,355],{"id":354},"código-de-resolución","Código de Resolución",[304,357,358],{},"Antes de plantear el código, es importante mencionar que este ejemplo se centra en la creación y manejo de hilos en Java, por lo que no se implementará una lógica real de descarga de archivos, sino que se simulará el proceso con tiempos de espera.",[304,360,361],{},"Así mismo partiremos de la siguiente estructura de clases:",[363,364,369],"pre",{"className":365,"code":367,"language":368},[366],"language-text",".\n└── concurrencia\u002F\n    └── src\u002F\n        └── app\u002F\n            └── concurrencia\u002F\n                ├── entities\u002F\n                │   ├── DownloadTask.java\n                │   └── ThreadManager.java\n                └── launch\u002F\n                    └── Main.java\n","text",[308,370,367],{"__ignoreMap":371},"",[373,374,376,377],"h3",{"id":375},"paso-1-crear-la-clase-downloadtask","Paso 1: Crear la clase ",[308,378,337],{},[304,380,381,382,384,385,387,388,391],{},"Para empezar, crearemos la clase ",[308,383,337],{}," que implementa ",[308,386,314],{},". Esta clase tendrá un constructor que recibe el nombre del archivo a descargar y un método ",[308,389,390],{},"run"," que simula la descarga.",[363,393,397],{"className":394,"code":395,"language":396,"meta":371,"style":371},"language-java shiki shiki-themes github-dark","package app.concurrencia.entities;\n\n\u002F**\n * Clase que representa una tarea de descarga de un archivo.\n *\u002F\npublic class DownloadTask implements Runnable {\n    \u002F**\n     * Nombre del archivo a descargar.\n     *\u002F\n    private String fileName;\n\n    \u002F**\n     * Constructor de la clase DownloadTask.\n     * \n     * @param fileName Nombre del archivo a descargar.\n     *\u002F\n    public DownloadTask(String fileName) {\n        this.fileName = fileName;\n    }\n\n    \u002F**\n     * Función que simula la descarga del archivo. Imprime el nombre del archivo que se está descargando, luego espera un tiempo aleatorio para simular el proceso de descarga y finalmente imprime un mensaje indicando que la descarga ha sido completada. Si el hilo es interrumpido durante la descarga, se captura la excepción y se imprime un mensaje indicando que la descarga ha sido interrumpida.\n     *\u002F\n    @Override\n    public void run() {\n        try {\n            IO.println(\"Descargando: \" + fileName);\n            \u002F\u002F Simular el tiempo de descarga\n            Thread.sleep((long) (Math.random() * 5000));\n            IO.println(\"Descarga completada: \" + fileName);\n        } catch (InterruptedException e) {\n            IO.println(\"Descarga interrumpida: \" + fileName);\n        }\n    }\n}\n","java",[308,398,399,412,419,426,432,438,460,466,472,478,487,492,497,503,509,525,530,547,563,569,574,579,585,590,599,613,621,643,649,681,697,714,730,736,741],{"__ignoreMap":371},[400,401,404,408],"span",{"class":402,"line":403},"line",1,[400,405,407],{"class":406},"snl16","package",[400,409,411],{"class":410},"s95oV"," app.concurrencia.entities;\n",[400,413,415],{"class":402,"line":414},2,[400,416,418],{"emptyLinePlaceholder":417},true,"\n",[400,420,422],{"class":402,"line":421},3,[400,423,425],{"class":424},"sAwPA","\u002F**\n",[400,427,429],{"class":402,"line":428},4,[400,430,431],{"class":424}," * Clase que representa una tarea de descarga de un archivo.\n",[400,433,435],{"class":402,"line":434},5,[400,436,437],{"class":424}," *\u002F\n",[400,439,441,444,447,451,454,457],{"class":402,"line":440},6,[400,442,443],{"class":406},"public",[400,445,446],{"class":406}," class",[400,448,450],{"class":449},"svObZ"," DownloadTask",[400,452,453],{"class":406}," implements",[400,455,456],{"class":449}," Runnable",[400,458,459],{"class":410}," {\n",[400,461,463],{"class":402,"line":462},7,[400,464,465],{"class":424},"    \u002F**\n",[400,467,469],{"class":402,"line":468},8,[400,470,471],{"class":424},"     * Nombre del archivo a descargar.\n",[400,473,475],{"class":402,"line":474},9,[400,476,477],{"class":424},"     *\u002F\n",[400,479,481,484],{"class":402,"line":480},10,[400,482,483],{"class":406},"    private",[400,485,486],{"class":410}," String fileName;\n",[400,488,490],{"class":402,"line":489},11,[400,491,418],{"emptyLinePlaceholder":417},[400,493,495],{"class":402,"line":494},12,[400,496,465],{"class":424},[400,498,500],{"class":402,"line":499},13,[400,501,502],{"class":424},"     * Constructor de la clase DownloadTask.\n",[400,504,506],{"class":402,"line":505},14,[400,507,508],{"class":424},"     * \n",[400,510,512,515,518,522],{"class":402,"line":511},15,[400,513,514],{"class":424},"     * ",[400,516,517],{"class":406},"@param",[400,519,521],{"class":520},"s9osk"," fileName",[400,523,524],{"class":424}," Nombre del archivo a descargar.\n",[400,526,528],{"class":402,"line":527},16,[400,529,477],{"class":424},[400,531,533,536,538,541,544],{"class":402,"line":532},17,[400,534,535],{"class":406},"    public",[400,537,450],{"class":449},[400,539,540],{"class":410},"(String ",[400,542,543],{"class":520},"fileName",[400,545,546],{"class":410},") {\n",[400,548,550,554,557,560],{"class":402,"line":549},18,[400,551,553],{"class":552},"sDLfK","        this",[400,555,556],{"class":410},".fileName ",[400,558,559],{"class":406},"=",[400,561,562],{"class":410}," fileName;\n",[400,564,566],{"class":402,"line":565},19,[400,567,568],{"class":410},"    }\n",[400,570,572],{"class":402,"line":571},20,[400,573,418],{"emptyLinePlaceholder":417},[400,575,577],{"class":402,"line":576},21,[400,578,465],{"class":424},[400,580,582],{"class":402,"line":581},22,[400,583,584],{"class":424},"     * Función que simula la descarga del archivo. Imprime el nombre del archivo que se está descargando, luego espera un tiempo aleatorio para simular el proceso de descarga y finalmente imprime un mensaje indicando que la descarga ha sido completada. Si el hilo es interrumpido durante la descarga, se captura la excepción y se imprime un mensaje indicando que la descarga ha sido interrumpida.\n",[400,586,588],{"class":402,"line":587},23,[400,589,477],{"class":424},[400,591,593,596],{"class":402,"line":592},24,[400,594,595],{"class":410},"    @",[400,597,598],{"class":406},"Override\n",[400,600,602,604,607,610],{"class":402,"line":601},25,[400,603,535],{"class":406},[400,605,606],{"class":406}," void",[400,608,609],{"class":449}," run",[400,611,612],{"class":410},"() {\n",[400,614,616,619],{"class":402,"line":615},26,[400,617,618],{"class":406},"        try",[400,620,459],{"class":410},[400,622,624,627,630,633,637,640],{"class":402,"line":623},27,[400,625,626],{"class":410},"            IO.",[400,628,629],{"class":449},"println",[400,631,632],{"class":410},"(",[400,634,636],{"class":635},"sU2Wk","\"Descargando: \"",[400,638,639],{"class":406}," +",[400,641,642],{"class":410}," fileName);\n",[400,644,646],{"class":402,"line":645},28,[400,647,648],{"class":424},"            \u002F\u002F Simular el tiempo de descarga\n",[400,650,652,655,657,660,663,666,669,672,675,678],{"class":402,"line":651},29,[400,653,654],{"class":410},"            Thread.",[400,656,318],{"class":449},[400,658,659],{"class":410},"((",[400,661,662],{"class":406},"long",[400,664,665],{"class":410},") (Math.",[400,667,668],{"class":449},"random",[400,670,671],{"class":410},"() ",[400,673,674],{"class":406},"*",[400,676,677],{"class":552}," 5000",[400,679,680],{"class":410},"));\n",[400,682,684,686,688,690,693,695],{"class":402,"line":683},30,[400,685,626],{"class":410},[400,687,629],{"class":449},[400,689,632],{"class":410},[400,691,692],{"class":635},"\"Descarga completada: \"",[400,694,639],{"class":406},[400,696,642],{"class":410},[400,698,700,703,706,709,712],{"class":402,"line":699},31,[400,701,702],{"class":410},"        } ",[400,704,705],{"class":406},"catch",[400,707,708],{"class":410}," (InterruptedException ",[400,710,711],{"class":520},"e",[400,713,546],{"class":410},[400,715,717,719,721,723,726,728],{"class":402,"line":716},32,[400,718,626],{"class":410},[400,720,629],{"class":449},[400,722,632],{"class":410},[400,724,725],{"class":635},"\"Descarga interrumpida: \"",[400,727,639],{"class":406},[400,729,642],{"class":410},[400,731,733],{"class":402,"line":732},33,[400,734,735],{"class":410},"        }\n",[400,737,739],{"class":402,"line":738},34,[400,740,568],{"class":410},[400,742,744],{"class":402,"line":743},35,[400,745,746],{"class":410},"}\n",[373,748,750,751],{"id":749},"paso-2-crear-la-clase-threadmanager","Paso 2: Crear la clase ",[308,752,753],{},"ThreadManager",[304,755,756,757,759],{},"A continuación, crearemos la clase ",[308,758,753],{}," que se encargará de crear y manejar los hilos para cada tarea de descarga. Esta clase tendrá un método para iniciar las descargas y otro para esperar a que todas las descargas se completen.",[363,761,763],{"className":394,"code":762,"language":396,"meta":371,"style":371},"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 tareas de descarga.\n *\u002F\npublic class ThreadManager {\n    \u002F**\n     * Lista de hilos que representan las tareas de descarga.\n     *\u002F\n    private List\u003CThread> threads;\n\n    \u002F**\n     * Constructor de la clase ThreadManager. Inicializa la lista de hilos.\n     *\u002F\n    public ThreadManager() {\n        threads = new ArrayList\u003C>();\n    }\n\n    \u002F**\n     * Función para iniciar las descargas. Crea un hilo para cada tarea de descarga y lo inicia.\n     * \n     * @param fileNames Lista de nombres de archivos a descargar.\n     *\u002F\n    public void startDownloads(List\u003CString> fileNames) {\n        for (String fileName : fileNames) {\n            Thread thread = new Thread(new DownloadTask(fileName));\n            threads.add(thread);\n            thread.start();\n        }\n    }\n\n    \u002F**\n     * Función para esperar a que todas las descargas se completen. Utiliza la función join para esperar a que cada hilo termine su ejecución.\n     *\u002F\n    public void waitForDownloads() {\n        for (Thread thread : threads) {\n            try {\n                thread.join();\n            } catch (InterruptedException e) {\n                IO.println(\"Esperando a que las descargas se completen ha sido interrumpido.\");\n            }\n        }\n    }\n}\n",[308,764,765,771,775,783,790,794,798,803,807,818,822,827,831,843,847,851,856,860,868,881,885,889,893,898,902,914,918,941,955,977,988,999,1003,1007,1011,1015,1021,1026,1038,1051,1059,1069,1083,1099,1105,1110,1115],{"__ignoreMap":371},[400,766,767,769],{"class":402,"line":403},[400,768,407],{"class":406},[400,770,411],{"class":410},[400,772,773],{"class":402,"line":414},[400,774,418],{"emptyLinePlaceholder":417},[400,776,777,780],{"class":402,"line":421},[400,778,779],{"class":406},"import",[400,781,782],{"class":410}," java.util.ArrayList;\n",[400,784,785,787],{"class":402,"line":428},[400,786,779],{"class":406},[400,788,789],{"class":410}," java.util.List;\n",[400,791,792],{"class":402,"line":434},[400,793,418],{"emptyLinePlaceholder":417},[400,795,796],{"class":402,"line":440},[400,797,425],{"class":424},[400,799,800],{"class":402,"line":462},[400,801,802],{"class":424}," * Clase que maneja la creación y ejecución de hilos para tareas de descarga.\n",[400,804,805],{"class":402,"line":468},[400,806,437],{"class":424},[400,808,809,811,813,816],{"class":402,"line":474},[400,810,443],{"class":406},[400,812,446],{"class":406},[400,814,815],{"class":449}," ThreadManager",[400,817,459],{"class":410},[400,819,820],{"class":402,"line":480},[400,821,465],{"class":424},[400,823,824],{"class":402,"line":489},[400,825,826],{"class":424},"     * Lista de hilos que representan las tareas de descarga.\n",[400,828,829],{"class":402,"line":494},[400,830,477],{"class":424},[400,832,833,835,838,840],{"class":402,"line":499},[400,834,483],{"class":406},[400,836,837],{"class":410}," List\u003C",[400,839,310],{"class":406},[400,841,842],{"class":410},"> threads;\n",[400,844,845],{"class":402,"line":505},[400,846,418],{"emptyLinePlaceholder":417},[400,848,849],{"class":402,"line":511},[400,850,465],{"class":424},[400,852,853],{"class":402,"line":527},[400,854,855],{"class":424},"     * Constructor de la clase ThreadManager. Inicializa la lista de hilos.\n",[400,857,858],{"class":402,"line":532},[400,859,477],{"class":424},[400,861,862,864,866],{"class":402,"line":549},[400,863,535],{"class":406},[400,865,815],{"class":449},[400,867,612],{"class":410},[400,869,870,873,875,878],{"class":402,"line":565},[400,871,872],{"class":410},"        threads ",[400,874,559],{"class":406},[400,876,877],{"class":406}," new",[400,879,880],{"class":410}," ArrayList\u003C>();\n",[400,882,883],{"class":402,"line":571},[400,884,568],{"class":410},[400,886,887],{"class":402,"line":576},[400,888,418],{"emptyLinePlaceholder":417},[400,890,891],{"class":402,"line":581},[400,892,465],{"class":424},[400,894,895],{"class":402,"line":587},[400,896,897],{"class":424},"     * Función para iniciar las descargas. Crea un hilo para cada tarea de descarga y lo inicia.\n",[400,899,900],{"class":402,"line":592},[400,901,508],{"class":424},[400,903,904,906,908,911],{"class":402,"line":601},[400,905,514],{"class":424},[400,907,517],{"class":406},[400,909,910],{"class":520}," fileNames",[400,912,913],{"class":424}," Lista de nombres de archivos a descargar.\n",[400,915,916],{"class":402,"line":615},[400,917,477],{"class":424},[400,919,920,922,924,927,930,933,936,939],{"class":402,"line":623},[400,921,535],{"class":406},[400,923,606],{"class":406},[400,925,926],{"class":449}," startDownloads",[400,928,929],{"class":410},"(List\u003C",[400,931,932],{"class":406},"String",[400,934,935],{"class":410},"> ",[400,937,938],{"class":520},"fileNames",[400,940,546],{"class":410},[400,942,943,946,949,952],{"class":402,"line":645},[400,944,945],{"class":406},"        for",[400,947,948],{"class":410}," (String fileName ",[400,950,951],{"class":406},":",[400,953,954],{"class":410}," fileNames) {\n",[400,956,957,960,962,964,967,969,972,974],{"class":402,"line":651},[400,958,959],{"class":410},"            Thread thread ",[400,961,559],{"class":406},[400,963,877],{"class":406},[400,965,966],{"class":449}," Thread",[400,968,632],{"class":410},[400,970,971],{"class":406},"new",[400,973,450],{"class":449},[400,975,976],{"class":410},"(fileName));\n",[400,978,979,982,985],{"class":402,"line":683},[400,980,981],{"class":410},"            threads.",[400,983,984],{"class":449},"add",[400,986,987],{"class":410},"(thread);\n",[400,989,990,993,996],{"class":402,"line":699},[400,991,992],{"class":410},"            thread.",[400,994,995],{"class":449},"start",[400,997,998],{"class":410},"();\n",[400,1000,1001],{"class":402,"line":716},[400,1002,735],{"class":410},[400,1004,1005],{"class":402,"line":732},[400,1006,568],{"class":410},[400,1008,1009],{"class":402,"line":738},[400,1010,418],{"emptyLinePlaceholder":417},[400,1012,1013],{"class":402,"line":743},[400,1014,465],{"class":424},[400,1016,1018],{"class":402,"line":1017},36,[400,1019,1020],{"class":424},"     * Función para esperar a que todas las descargas se completen. Utiliza la función join para esperar a que cada hilo termine su ejecución.\n",[400,1022,1024],{"class":402,"line":1023},37,[400,1025,477],{"class":424},[400,1027,1029,1031,1033,1036],{"class":402,"line":1028},38,[400,1030,535],{"class":406},[400,1032,606],{"class":406},[400,1034,1035],{"class":449}," waitForDownloads",[400,1037,612],{"class":410},[400,1039,1041,1043,1046,1048],{"class":402,"line":1040},39,[400,1042,945],{"class":406},[400,1044,1045],{"class":410}," (Thread thread ",[400,1047,951],{"class":406},[400,1049,1050],{"class":410}," threads) {\n",[400,1052,1054,1057],{"class":402,"line":1053},40,[400,1055,1056],{"class":406},"            try",[400,1058,459],{"class":410},[400,1060,1062,1065,1067],{"class":402,"line":1061},41,[400,1063,1064],{"class":410},"                thread.",[400,1066,322],{"class":449},[400,1068,998],{"class":410},[400,1070,1072,1075,1077,1079,1081],{"class":402,"line":1071},42,[400,1073,1074],{"class":410},"            } ",[400,1076,705],{"class":406},[400,1078,708],{"class":410},[400,1080,711],{"class":520},[400,1082,546],{"class":410},[400,1084,1086,1089,1091,1093,1096],{"class":402,"line":1085},43,[400,1087,1088],{"class":410},"                IO.",[400,1090,629],{"class":449},[400,1092,632],{"class":410},[400,1094,1095],{"class":635},"\"Esperando a que las descargas se completen ha sido interrumpido.\"",[400,1097,1098],{"class":410},");\n",[400,1100,1102],{"class":402,"line":1101},44,[400,1103,1104],{"class":410},"            }\n",[400,1106,1108],{"class":402,"line":1107},45,[400,1109,735],{"class":410},[400,1111,1113],{"class":402,"line":1112},46,[400,1114,568],{"class":410},[400,1116,1118],{"class":402,"line":1117},47,[400,1119,746],{"class":410},[373,1121,1123,1124],{"id":1122},"paso-3-crear-la-clase-main","Paso 3: Crear la clase ",[308,1125,1126],{},"Main",[304,1128,1129,1130,1132,1133,1135],{},"Finalmente, crearemos la clase ",[308,1131,1126],{}," que será el punto de entrada del programa. En esta clase, crearemos una instancia de ",[308,1134,753],{},", iniciaremos las descargas y esperaremos a que todas las descargas se completen.",[363,1137,1139],{"className":394,"code":1138,"language":396,"meta":371,"style":371},"package app.concurrencia.launch;\n\nimport app.concurrencia.entities.ThreadManager;\nimport java.util.Arrays;\nimport java.util.List;\n\n\u002F**\n * Clase principal del programa que simula la descarga de archivos utilizando hilos.\n *\u002F\npublic class Main {\n    void main() {\n        \u002F\u002F Lista de archivos a descargar\n        List\u003CString> fileNames = Arrays.asList(\"archivo1.txt\", \"archivo2.txt\", \"archivo3.txt\");\n\n        \u002F\u002F Crear una instancia de ThreadManager\n        ThreadManager threadManager = new ThreadManager();\n\n        \u002F\u002F Iniciar las descargas\n        threadManager.startDownloads(fileNames);\n\n        \u002F\u002F Esperar a que todas las descargas se completen\n        threadManager.waitForDownloads();\n\n        IO.println(\"Todas las descargas han sido completadas.\");\n    }\n}\n",[308,1140,1141,1148,1152,1159,1166,1172,1176,1180,1185,1189,1200,1210,1215,1250,1254,1259,1272,1276,1281,1292,1296,1301,1310,1314,1328,1332],{"__ignoreMap":371},[400,1142,1143,1145],{"class":402,"line":403},[400,1144,407],{"class":406},[400,1146,1147],{"class":410}," app.concurrencia.launch;\n",[400,1149,1150],{"class":402,"line":414},[400,1151,418],{"emptyLinePlaceholder":417},[400,1153,1154,1156],{"class":402,"line":421},[400,1155,779],{"class":406},[400,1157,1158],{"class":410}," app.concurrencia.entities.ThreadManager;\n",[400,1160,1161,1163],{"class":402,"line":428},[400,1162,779],{"class":406},[400,1164,1165],{"class":410}," java.util.Arrays;\n",[400,1167,1168,1170],{"class":402,"line":434},[400,1169,779],{"class":406},[400,1171,789],{"class":410},[400,1173,1174],{"class":402,"line":440},[400,1175,418],{"emptyLinePlaceholder":417},[400,1177,1178],{"class":402,"line":462},[400,1179,425],{"class":424},[400,1181,1182],{"class":402,"line":468},[400,1183,1184],{"class":424}," * Clase principal del programa que simula la descarga de archivos utilizando hilos.\n",[400,1186,1187],{"class":402,"line":474},[400,1188,437],{"class":424},[400,1190,1191,1193,1195,1198],{"class":402,"line":480},[400,1192,443],{"class":406},[400,1194,446],{"class":406},[400,1196,1197],{"class":449}," Main",[400,1199,459],{"class":410},[400,1201,1202,1205,1208],{"class":402,"line":489},[400,1203,1204],{"class":406},"    void",[400,1206,1207],{"class":449}," main",[400,1209,612],{"class":410},[400,1211,1212],{"class":402,"line":494},[400,1213,1214],{"class":424},"        \u002F\u002F Lista de archivos a descargar\n",[400,1216,1217,1220,1222,1225,1227,1230,1233,1235,1238,1240,1243,1245,1248],{"class":402,"line":499},[400,1218,1219],{"class":410},"        List\u003C",[400,1221,932],{"class":406},[400,1223,1224],{"class":410},"> fileNames ",[400,1226,559],{"class":406},[400,1228,1229],{"class":410}," Arrays.",[400,1231,1232],{"class":449},"asList",[400,1234,632],{"class":410},[400,1236,1237],{"class":635},"\"archivo1.txt\"",[400,1239,319],{"class":410},[400,1241,1242],{"class":635},"\"archivo2.txt\"",[400,1244,319],{"class":410},[400,1246,1247],{"class":635},"\"archivo3.txt\"",[400,1249,1098],{"class":410},[400,1251,1252],{"class":402,"line":505},[400,1253,418],{"emptyLinePlaceholder":417},[400,1255,1256],{"class":402,"line":511},[400,1257,1258],{"class":424},"        \u002F\u002F Crear una instancia de ThreadManager\n",[400,1260,1261,1264,1266,1268,1270],{"class":402,"line":527},[400,1262,1263],{"class":410},"        ThreadManager threadManager ",[400,1265,559],{"class":406},[400,1267,877],{"class":406},[400,1269,815],{"class":449},[400,1271,998],{"class":410},[400,1273,1274],{"class":402,"line":532},[400,1275,418],{"emptyLinePlaceholder":417},[400,1277,1278],{"class":402,"line":549},[400,1279,1280],{"class":424},"        \u002F\u002F Iniciar las descargas\n",[400,1282,1283,1286,1289],{"class":402,"line":565},[400,1284,1285],{"class":410},"        threadManager.",[400,1287,1288],{"class":449},"startDownloads",[400,1290,1291],{"class":410},"(fileNames);\n",[400,1293,1294],{"class":402,"line":571},[400,1295,418],{"emptyLinePlaceholder":417},[400,1297,1298],{"class":402,"line":576},[400,1299,1300],{"class":424},"        \u002F\u002F Esperar a que todas las descargas se completen\n",[400,1302,1303,1305,1308],{"class":402,"line":581},[400,1304,1285],{"class":410},[400,1306,1307],{"class":449},"waitForDownloads",[400,1309,998],{"class":410},[400,1311,1312],{"class":402,"line":587},[400,1313,418],{"emptyLinePlaceholder":417},[400,1315,1316,1319,1321,1323,1326],{"class":402,"line":592},[400,1317,1318],{"class":410},"        IO.",[400,1320,629],{"class":449},[400,1322,632],{"class":410},[400,1324,1325],{"class":635},"\"Todas las descargas han sido completadas.\"",[400,1327,1098],{"class":410},[400,1329,1330],{"class":402,"line":601},[400,1331,568],{"class":410},[400,1333,1334],{"class":402,"line":615},[400,1335,746],{"class":410},[325,1337,1339],{"id":1338},"salida-esperada","Salida Esperada",[304,1341,1342],{},"Al ejecutar el programa, se espera ver una salida similar a la siguiente, aunque el orden de las descargas puede variar debido a la naturaleza concurrente de los hilos:",[363,1344,1347],{"className":1345,"code":1346,"language":368},[366],"Descargando: archivo1.txt\nDescargando: archivo2.txt\nDescargando: archivo3.txt\nDescarga completada: archivo2.txt\nDescarga completada: archivo1.txt\nDescarga completada: archivo3.txt\nTodas las descargas han sido completadas.\n",[308,1348,1346],{"__ignoreMap":371},[304,1350,1351],{},"Notarás que puedes ver que las descargas se inician al mismo tiempo, pero el orden de finalización puede variar debido a los tiempos de descarga simulados. Además, si interrumpes el programa mientras las descargas están en progreso, podrías ver mensajes indicando que las descargas han sido interrumpidas.",[325,1353,1355],{"id":1354},"conclusión","Conclusión",[304,1357,1358,1359,384,1361,1363,1364,1366,1367,319,1369,1371],{},"En este ejemplo, hemos visto cómo utilizar hilos en Java para ejecutar tareas concurrentes. Hemos creado una clase ",[308,1360,337],{},[308,1362,314],{}," para simular la descarga de archivos, y una clase ",[308,1365,753],{}," para manejar la creación y ejecución de los hilos. Además, hemos utilizado las funciones ",[308,1368,318],{},[308,1370,322],{}," e interrupciones para controlar la ejecución de los hilos. Este ejemplo demuestra cómo la concurrencia puede ser manejada en Java utilizando hilos, lo que permite ejecutar múltiples tareas al mismo tiempo de manera eficiente.",[1373,1374,1375],"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":371,"searchDepth":414,"depth":414,"links":1377},[1378,1379,1387,1388],{"id":327,"depth":414,"text":328},{"id":354,"depth":414,"text":355,"children":1380},[1381,1383,1385],{"id":375,"depth":421,"text":1382},"Paso 1: Crear la clase DownloadTask",{"id":749,"depth":421,"text":1384},"Paso 2: Crear la clase ThreadManager",{"id":1122,"depth":421,"text":1386},"Paso 3: Crear la clase Main",{"id":1338,"depth":414,"text":1339},{"id":1354,"depth":414,"text":1355},"Ejemplo de cómo usar hilos en Java usando Thread y Runnable, además de las funciones sleep y join e interrupciones.","md",null,{"editButton":104},{"icon":83},{"title":234,"description":1389},"WY7p7zyey-Wx5HTMPXb50JHSwWkFr6wGm_ZZ2BBSsQ4",[1397,1399],{"title":230,"path":231,"stem":232,"description":1398,"children":-1},"En este ejemplo, se muestra cómo estilizar componentes Swing utilizando delegadores para personalizar su apariencia.",{"title":238,"path":239,"stem":240,"description":1400,"icon":83,"children":-1},"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.",1775101375801]