[{"data":1,"prerenderedAt":1816},["ShallowReactive",2],{"navigation_docs":3,"-concurrencia-semaforos":298,"-concurrencia-semaforos-surround":1811},[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":137,"body":300,"description":1804,"extension":1805,"links":1806,"meta":1807,"navigation":1808,"path":138,"seo":1809,"stem":139,"__hash__":1810},"docs\u002F4.concurrencia\u002F08.semaforos.md",{"type":301,"value":302,"toc":1794},"minimark",[303,307,319,599,614,620,735,738,743,796,800,803,829,832,836,839,904,919,923,926,1198,1440,1450,1454,1460,1485,1492,1496,1513,1543,1549,1553,1556,1769,1783,1787,1790],[304,305,306],"p",{},"En Java, un semáforo es una herramienta de sincronización que se utiliza para controlar el acceso a recursos compartidos en un entorno concurrente. Un semáforo mantiene un contador que representa el número de permisos disponibles para acceder a un recurso. Los hilos pueden adquirir o liberar permisos del semáforo para acceder al recurso compartido.",[304,308,309,310,314,315,318],{},"En Java, la clase ",[311,312,313],"code",{},"Semaphore"," del paquete ",[311,316,317],{},"java.util.concurrent"," se utiliza para implementar semáforos. A continuación, se muestra un ejemplo de cómo utilizar un semáforo para controlar el acceso a un recurso compartido:",[320,321,326],"pre",{"className":322,"code":323,"language":324,"meta":325,"style":325},"language-java shiki shiki-themes github-dark","public class Worker implements Runnable {\n    private Semaphore semaphore;\n\n    public Worker(Semaphore semaphore) {\n        this.semaphore = semaphore;\n    }\n\n    @Override\n    public void run() {\n        try {\n            \u002F\u002F Adquirir un permiso del semáforo\n            semaphore.acquire();\n            System.out.println(\"Worker \" + Thread.currentThread().getName() + \" is working...\");\n            Thread.sleep(2000); \u002F\u002F Simular trabajo\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        } finally {\n            \u002F\u002F Liberar el permiso del semáforo\n            semaphore.release();\n        }\n    }\n}\n","java","",[311,327,328,354,363,370,388,404,410,415,424,438,446,453,465,508,528,545,556,566,572,582,588,593],{"__ignoreMap":325},[329,330,333,337,340,344,347,350],"span",{"class":331,"line":332},"line",1,[329,334,336],{"class":335},"snl16","public",[329,338,339],{"class":335}," class",[329,341,343],{"class":342},"svObZ"," Worker",[329,345,346],{"class":335}," implements",[329,348,349],{"class":342}," Runnable",[329,351,353],{"class":352},"s95oV"," {\n",[329,355,357,360],{"class":331,"line":356},2,[329,358,359],{"class":335},"    private",[329,361,362],{"class":352}," Semaphore semaphore;\n",[329,364,366],{"class":331,"line":365},3,[329,367,369],{"emptyLinePlaceholder":368},true,"\n",[329,371,373,376,378,381,385],{"class":331,"line":372},4,[329,374,375],{"class":335},"    public",[329,377,343],{"class":342},[329,379,380],{"class":352},"(Semaphore ",[329,382,384],{"class":383},"s9osk","semaphore",[329,386,387],{"class":352},") {\n",[329,389,391,395,398,401],{"class":331,"line":390},5,[329,392,394],{"class":393},"sDLfK","        this",[329,396,397],{"class":352},".semaphore ",[329,399,400],{"class":335},"=",[329,402,403],{"class":352}," semaphore;\n",[329,405,407],{"class":331,"line":406},6,[329,408,409],{"class":352},"    }\n",[329,411,413],{"class":331,"line":412},7,[329,414,369],{"emptyLinePlaceholder":368},[329,416,418,421],{"class":331,"line":417},8,[329,419,420],{"class":352},"    @",[329,422,423],{"class":335},"Override\n",[329,425,427,429,432,435],{"class":331,"line":426},9,[329,428,375],{"class":335},[329,430,431],{"class":335}," void",[329,433,434],{"class":342}," run",[329,436,437],{"class":352},"() {\n",[329,439,441,444],{"class":331,"line":440},10,[329,442,443],{"class":335},"        try",[329,445,353],{"class":352},[329,447,449],{"class":331,"line":448},11,[329,450,452],{"class":451},"sAwPA","            \u002F\u002F Adquirir un permiso del semáforo\n",[329,454,456,459,462],{"class":331,"line":455},12,[329,457,458],{"class":352},"            semaphore.",[329,460,461],{"class":342},"acquire",[329,463,464],{"class":352},"();\n",[329,466,468,471,474,477,481,484,487,490,493,496,499,502,505],{"class":331,"line":467},13,[329,469,470],{"class":352},"            System.out.",[329,472,473],{"class":342},"println",[329,475,476],{"class":352},"(",[329,478,480],{"class":479},"sU2Wk","\"Worker \"",[329,482,483],{"class":335}," +",[329,485,486],{"class":352}," Thread.",[329,488,489],{"class":342},"currentThread",[329,491,492],{"class":352},"().",[329,494,495],{"class":342},"getName",[329,497,498],{"class":352},"() ",[329,500,501],{"class":335},"+",[329,503,504],{"class":479}," \" is working...\"",[329,506,507],{"class":352},");\n",[329,509,511,514,517,519,522,525],{"class":331,"line":510},14,[329,512,513],{"class":352},"            Thread.",[329,515,516],{"class":342},"sleep",[329,518,476],{"class":352},[329,520,521],{"class":393},"2000",[329,523,524],{"class":352},"); ",[329,526,527],{"class":451},"\u002F\u002F Simular trabajo\n",[329,529,531,534,537,540,543],{"class":331,"line":530},15,[329,532,533],{"class":352},"        } ",[329,535,536],{"class":335},"catch",[329,538,539],{"class":352}," (InterruptedException ",[329,541,542],{"class":383},"e",[329,544,387],{"class":352},[329,546,548,551,554],{"class":331,"line":547},16,[329,549,550],{"class":352},"            e.",[329,552,553],{"class":342},"printStackTrace",[329,555,464],{"class":352},[329,557,559,561,564],{"class":331,"line":558},17,[329,560,533],{"class":352},[329,562,563],{"class":335},"finally",[329,565,353],{"class":352},[329,567,569],{"class":331,"line":568},18,[329,570,571],{"class":451},"            \u002F\u002F Liberar el permiso del semáforo\n",[329,573,575,577,580],{"class":331,"line":574},19,[329,576,458],{"class":352},[329,578,579],{"class":342},"release",[329,581,464],{"class":352},[329,583,585],{"class":331,"line":584},20,[329,586,587],{"class":352},"        }\n",[329,589,591],{"class":331,"line":590},21,[329,592,409],{"class":352},[329,594,596],{"class":331,"line":595},22,[329,597,598],{"class":352},"}\n",[304,600,601,602,605,606,609,610,613],{},"En este ejemplo, la clase ",[311,603,604],{},"Worker"," implementa la interfaz ",[311,607,608],{},"Runnable"," y utiliza un semáforo para controlar el acceso a un recurso compartido. En el método ",[311,611,612],{},"run()",", el hilo adquiere un permiso del semáforo antes de realizar su trabajo y lo libera después de completar su tarea.",[304,615,616,617,619],{},"Para utilizar la clase ",[311,618,604],{},", podemos crear un semáforo con un número específico de permisos y luego iniciar varios hilos que intenten adquirir esos permisos:",[320,621,623],{"className":322,"code":622,"language":324,"meta":325,"style":325},"void main(String[] args) {\n    Semaphore semaphore = new Semaphore(3); \u002F\u002F Permitir hasta 3 hilos al mismo tiempo\n\n    for (int i = 0; i \u003C 10; i++) {\n        new Thread(new Worker(semaphore)).start();\n    }\n}\n",[311,624,625,641,664,668,704,727,731],{"__ignoreMap":325},[329,626,627,630,633,635,638],{"class":331,"line":332},[329,628,629],{"class":335},"void",[329,631,632],{"class":342}," main",[329,634,476],{"class":352},[329,636,637],{"class":335},"String",[329,639,640],{"class":352},"[] args) {\n",[329,642,643,646,648,651,654,656,659,661],{"class":331,"line":356},[329,644,645],{"class":352},"    Semaphore semaphore ",[329,647,400],{"class":335},[329,649,650],{"class":335}," new",[329,652,653],{"class":342}," Semaphore",[329,655,476],{"class":352},[329,657,658],{"class":393},"3",[329,660,524],{"class":352},[329,662,663],{"class":451},"\u002F\u002F Permitir hasta 3 hilos al mismo tiempo\n",[329,665,666],{"class":331,"line":365},[329,667,369],{"emptyLinePlaceholder":368},[329,669,670,673,676,679,682,684,687,690,693,696,699,702],{"class":331,"line":372},[329,671,672],{"class":335},"    for",[329,674,675],{"class":352}," (",[329,677,678],{"class":335},"int",[329,680,681],{"class":352}," i ",[329,683,400],{"class":335},[329,685,686],{"class":393}," 0",[329,688,689],{"class":352},"; i ",[329,691,692],{"class":335},"\u003C",[329,694,695],{"class":393}," 10",[329,697,698],{"class":352},"; i",[329,700,701],{"class":335},"++",[329,703,387],{"class":352},[329,705,706,709,712,714,717,719,722,725],{"class":331,"line":390},[329,707,708],{"class":335},"        new",[329,710,711],{"class":342}," Thread",[329,713,476],{"class":352},[329,715,716],{"class":335},"new",[329,718,343],{"class":342},[329,720,721],{"class":352},"(semaphore)).",[329,723,724],{"class":342},"start",[329,726,464],{"class":352},[329,728,729],{"class":331,"line":406},[329,730,409],{"class":352},[329,732,733],{"class":331,"line":412},[329,734,598],{"class":352},[304,736,737],{},"En este ejemplo, se crea un semáforo con 3 permisos, lo que significa que hasta 3 hilos pueden acceder al recurso compartido al mismo tiempo. Al iniciar 10 hilos, algunos de ellos tendrán que esperar hasta que otros liberen sus permisos para poder acceder al recurso compartido.",[739,740,742],"h2",{"id":741},"funciones-del-semáforo","Funciones del semáforo",[744,745,746,753,759,765,779,790],"ul",{},[747,748,749,752],"li",{},[311,750,751],{},"acquire()",": Adquiere un permiso del semáforo. Si no hay permisos disponibles, el hilo se bloquea hasta que un permiso esté disponible.",[747,754,755,758],{},[311,756,757],{},"release()",": Libera un permiso del semáforo, permitiendo que otros hilos puedan adquirirlo.",[747,760,761,764],{},[311,762,763],{},"availablePermits()",": Devuelve el número de permisos disponibles en el semáforo.",[747,766,767,770,771,774,775,778],{},[311,768,769],{},"tryAcquire()",": Intenta adquirir un permiso del semáforo sin bloquear el hilo. Devuelve ",[311,772,773],{},"true"," si se adquirió un permiso, o ",[311,776,777],{},"false"," si no hay permisos disponibles.",[747,780,781,784,785,774,787,789],{},[311,782,783],{},"tryAcquire(long timeout, TimeUnit unit)",": Intenta adquirir un permiso del semáforo, bloqueando el hilo durante un tiempo máximo especificado. Devuelve ",[311,786,773],{},[311,788,777],{}," si no se adquirió dentro del tiempo especificado.",[747,791,792,795],{},[311,793,794],{},"drainPermits()",": Elimina todos los permisos disponibles del semáforo y devuelve el número de permisos eliminados.",[739,797,799],{"id":798},"exclusión-mutua-con-semáforos","Exclusión mutua con semáforos",[304,801,802],{},"Los semáforos también se pueden utilizar para implementar exclusión mutua, lo que significa que solo un hilo puede acceder a un recurso compartido en un momento dado. Para lograr esto, se puede crear un semáforo con un solo permiso:",[320,804,806],{"className":322,"code":805,"language":324,"meta":325,"style":325},"Semaphore mutex = new Semaphore(1); \u002F\u002F Semáforo de exclusión mutua\n",[311,807,808],{"__ignoreMap":325},[329,809,810,813,815,817,819,821,824,826],{"class":331,"line":332},[329,811,812],{"class":352},"Semaphore mutex ",[329,814,400],{"class":335},[329,816,650],{"class":335},[329,818,653],{"class":342},[329,820,476],{"class":352},[329,822,823],{"class":393},"1",[329,825,524],{"class":352},[329,827,828],{"class":451},"\u002F\u002F Semáforo de exclusión mutua\n",[304,830,831],{},"En este caso, solo un hilo podrá adquirir el permiso del semáforo y acceder al recurso compartido, mientras que los demás hilos tendrán que esperar hasta que el permiso sea liberado.",[739,833,835],{"id":834},"sincronización-genérica-con-semáforos","Sincronización Genérica con semáforos",[304,837,838],{},"Además de la exclusión mutua, los semáforos también se pueden utilizar para sincronizar hilos de manera más general. Por ejemplo, se pueden utilizar para implementar un sistema de productores y consumidores, donde los productores generan datos y los consumidores los consumen. En este caso, se pueden utilizar dos semáforos: uno para controlar el acceso a un buffer compartido y otro para contar el número de elementos en el buffer.",[320,840,842],{"className":322,"code":841,"language":324,"meta":325,"style":325},"Semaphore empty = new Semaphore(10); \u002F\u002F Semáforo para contar los espacios vacíos en el buffer\nSemaphore full = new Semaphore(0); \u002F\u002F Semáforo para contar los elementos en el buffer\nSemaphore mutex = new Semaphore(1); \u002F\u002F Semáforo de exclusión mutua\n",[311,843,844,865,886],{"__ignoreMap":325},[329,845,846,849,851,853,855,857,860,862],{"class":331,"line":332},[329,847,848],{"class":352},"Semaphore empty ",[329,850,400],{"class":335},[329,852,650],{"class":335},[329,854,653],{"class":342},[329,856,476],{"class":352},[329,858,859],{"class":393},"10",[329,861,524],{"class":352},[329,863,864],{"class":451},"\u002F\u002F Semáforo para contar los espacios vacíos en el buffer\n",[329,866,867,870,872,874,876,878,881,883],{"class":331,"line":356},[329,868,869],{"class":352},"Semaphore full ",[329,871,400],{"class":335},[329,873,650],{"class":335},[329,875,653],{"class":342},[329,877,476],{"class":352},[329,879,880],{"class":393},"0",[329,882,524],{"class":352},[329,884,885],{"class":451},"\u002F\u002F Semáforo para contar los elementos en el buffer\n",[329,887,888,890,892,894,896,898,900,902],{"class":331,"line":365},[329,889,812],{"class":352},[329,891,400],{"class":335},[329,893,650],{"class":335},[329,895,653],{"class":342},[329,897,476],{"class":352},[329,899,823],{"class":393},[329,901,524],{"class":352},[329,903,828],{"class":451},[304,905,906,907,910,911,914,915,918],{},"En este ejemplo, el semáforo ",[311,908,909],{},"empty"," se utiliza para contar el número de espacios vacíos en el buffer, mientras que el semáforo ",[311,912,913],{},"full"," se utiliza para contar el número de elementos en el buffer. El semáforo ",[311,916,917],{},"mutex"," se utiliza para garantizar la exclusión mutua al acceder al buffer compartido.",[739,920,922],{"id":921},"ejemplo-de-productores-y-consumidores-con-semáforos","Ejemplo de Productores y Consumidores con Semáforos",[304,924,925],{},"A continuación, se muestra un ejemplo de cómo implementar un sistema de productores y consumidores utilizando semáforos en Java:",[320,927,929],{"className":322,"code":928,"language":324,"meta":325,"style":325},"public class Producer implements Runnable {\n    private Semaphore empty;\n    private Semaphore full;\n    private Semaphore mutex;\n    private Buffer buffer;\n\n    public Producer(Semaphore empty, Semaphore full, Semaphore mutex, Buffer buffer) {\n        this.empty = empty;\n        this.full = full;\n        this.mutex = mutex;\n        this.buffer = buffer;\n    }\n\n    @Override\n    public void run() {\n        try {\n            while (true) {\n                empty.acquire(); \u002F\u002F Esperar a que haya espacio en el buffer\n                mutex.acquire(); \u002F\u002F Adquirir exclusión mutua\n                buffer.add(); \u002F\u002F Agregar un elemento al buffer\n                mutex.release(); \u002F\u002F Liberar exclusión mutua\n                full.release(); \u002F\u002F Incrementar el contador de elementos en el buffer\n            }\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}\n\n",[311,930,931,946,953,960,967,974,978,1005,1017,1029,1041,1053,1057,1061,1067,1077,1083,1094,1107,1119,1132,1143,1155,1161,1174,1183,1188,1193],{"__ignoreMap":325},[329,932,933,935,937,940,942,944],{"class":331,"line":332},[329,934,336],{"class":335},[329,936,339],{"class":335},[329,938,939],{"class":342}," Producer",[329,941,346],{"class":335},[329,943,349],{"class":342},[329,945,353],{"class":352},[329,947,948,950],{"class":331,"line":356},[329,949,359],{"class":335},[329,951,952],{"class":352}," Semaphore empty;\n",[329,954,955,957],{"class":331,"line":365},[329,956,359],{"class":335},[329,958,959],{"class":352}," Semaphore full;\n",[329,961,962,964],{"class":331,"line":372},[329,963,359],{"class":335},[329,965,966],{"class":352}," Semaphore mutex;\n",[329,968,969,971],{"class":331,"line":390},[329,970,359],{"class":335},[329,972,973],{"class":352}," Buffer buffer;\n",[329,975,976],{"class":331,"line":406},[329,977,369],{"emptyLinePlaceholder":368},[329,979,980,982,984,986,988,991,993,995,997,1000,1003],{"class":331,"line":412},[329,981,375],{"class":335},[329,983,939],{"class":342},[329,985,380],{"class":352},[329,987,909],{"class":383},[329,989,990],{"class":352},", Semaphore ",[329,992,913],{"class":383},[329,994,990],{"class":352},[329,996,917],{"class":383},[329,998,999],{"class":352},", Buffer ",[329,1001,1002],{"class":383},"buffer",[329,1004,387],{"class":352},[329,1006,1007,1009,1012,1014],{"class":331,"line":417},[329,1008,394],{"class":393},[329,1010,1011],{"class":352},".empty ",[329,1013,400],{"class":335},[329,1015,1016],{"class":352}," empty;\n",[329,1018,1019,1021,1024,1026],{"class":331,"line":426},[329,1020,394],{"class":393},[329,1022,1023],{"class":352},".full ",[329,1025,400],{"class":335},[329,1027,1028],{"class":352}," full;\n",[329,1030,1031,1033,1036,1038],{"class":331,"line":440},[329,1032,394],{"class":393},[329,1034,1035],{"class":352},".mutex ",[329,1037,400],{"class":335},[329,1039,1040],{"class":352}," mutex;\n",[329,1042,1043,1045,1048,1050],{"class":331,"line":448},[329,1044,394],{"class":393},[329,1046,1047],{"class":352},".buffer ",[329,1049,400],{"class":335},[329,1051,1052],{"class":352}," buffer;\n",[329,1054,1055],{"class":331,"line":455},[329,1056,409],{"class":352},[329,1058,1059],{"class":331,"line":467},[329,1060,369],{"emptyLinePlaceholder":368},[329,1062,1063,1065],{"class":331,"line":510},[329,1064,420],{"class":352},[329,1066,423],{"class":335},[329,1068,1069,1071,1073,1075],{"class":331,"line":530},[329,1070,375],{"class":335},[329,1072,431],{"class":335},[329,1074,434],{"class":342},[329,1076,437],{"class":352},[329,1078,1079,1081],{"class":331,"line":547},[329,1080,443],{"class":335},[329,1082,353],{"class":352},[329,1084,1085,1088,1090,1092],{"class":331,"line":558},[329,1086,1087],{"class":335},"            while",[329,1089,675],{"class":352},[329,1091,773],{"class":393},[329,1093,387],{"class":352},[329,1095,1096,1099,1101,1104],{"class":331,"line":568},[329,1097,1098],{"class":352},"                empty.",[329,1100,461],{"class":342},[329,1102,1103],{"class":352},"(); ",[329,1105,1106],{"class":451},"\u002F\u002F Esperar a que haya espacio en el buffer\n",[329,1108,1109,1112,1114,1116],{"class":331,"line":574},[329,1110,1111],{"class":352},"                mutex.",[329,1113,461],{"class":342},[329,1115,1103],{"class":352},[329,1117,1118],{"class":451},"\u002F\u002F Adquirir exclusión mutua\n",[329,1120,1121,1124,1127,1129],{"class":331,"line":584},[329,1122,1123],{"class":352},"                buffer.",[329,1125,1126],{"class":342},"add",[329,1128,1103],{"class":352},[329,1130,1131],{"class":451},"\u002F\u002F Agregar un elemento al buffer\n",[329,1133,1134,1136,1138,1140],{"class":331,"line":590},[329,1135,1111],{"class":352},[329,1137,579],{"class":342},[329,1139,1103],{"class":352},[329,1141,1142],{"class":451},"\u002F\u002F Liberar exclusión mutua\n",[329,1144,1145,1148,1150,1152],{"class":331,"line":595},[329,1146,1147],{"class":352},"                full.",[329,1149,579],{"class":342},[329,1151,1103],{"class":352},[329,1153,1154],{"class":451},"\u002F\u002F Incrementar el contador de elementos en el buffer\n",[329,1156,1158],{"class":331,"line":1157},23,[329,1159,1160],{"class":352},"            }\n",[329,1162,1164,1166,1168,1170,1172],{"class":331,"line":1163},24,[329,1165,533],{"class":352},[329,1167,536],{"class":335},[329,1169,539],{"class":352},[329,1171,542],{"class":383},[329,1173,387],{"class":352},[329,1175,1177,1179,1181],{"class":331,"line":1176},25,[329,1178,550],{"class":352},[329,1180,553],{"class":342},[329,1182,464],{"class":352},[329,1184,1186],{"class":331,"line":1185},26,[329,1187,587],{"class":352},[329,1189,1191],{"class":331,"line":1190},27,[329,1192,409],{"class":352},[329,1194,1196],{"class":331,"line":1195},28,[329,1197,598],{"class":352},[320,1199,1201],{"className":322,"code":1200,"language":324,"meta":325,"style":325},"public class Consumer implements Runnable {\n    private Semaphore empty;\n    private Semaphore full;\n    private Semaphore mutex;\n    private Buffer buffer;\n\n    public Consumer(Semaphore empty, Semaphore full, Semaphore mutex, Buffer buffer) {\n        this.empty = empty;\n        this.full = full;\n        this.mutex = mutex;\n        this.buffer = buffer;\n    }\n\n    @Override\n    public void run() {\n        try {\n            while (true) {\n                full.acquire(); \u002F\u002F Esperar a que haya elementos en el buffer\n                mutex.acquire(); \u002F\u002F Adquirir exclusión mutua\n                buffer.remove(); \u002F\u002F Eliminar un elemento del buffer\n                mutex.release(); \u002F\u002F Liberar exclusión mutua\n                empty.release(); \u002F\u002F Incrementar el contador de espacios vacíos en el buffer\n            }\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}\n",[311,1202,1203,1218,1224,1230,1236,1242,1246,1270,1280,1290,1300,1310,1314,1318,1324,1334,1340,1350,1361,1371,1383,1393,1404,1408,1420,1428,1432,1436],{"__ignoreMap":325},[329,1204,1205,1207,1209,1212,1214,1216],{"class":331,"line":332},[329,1206,336],{"class":335},[329,1208,339],{"class":335},[329,1210,1211],{"class":342}," Consumer",[329,1213,346],{"class":335},[329,1215,349],{"class":342},[329,1217,353],{"class":352},[329,1219,1220,1222],{"class":331,"line":356},[329,1221,359],{"class":335},[329,1223,952],{"class":352},[329,1225,1226,1228],{"class":331,"line":365},[329,1227,359],{"class":335},[329,1229,959],{"class":352},[329,1231,1232,1234],{"class":331,"line":372},[329,1233,359],{"class":335},[329,1235,966],{"class":352},[329,1237,1238,1240],{"class":331,"line":390},[329,1239,359],{"class":335},[329,1241,973],{"class":352},[329,1243,1244],{"class":331,"line":406},[329,1245,369],{"emptyLinePlaceholder":368},[329,1247,1248,1250,1252,1254,1256,1258,1260,1262,1264,1266,1268],{"class":331,"line":412},[329,1249,375],{"class":335},[329,1251,1211],{"class":342},[329,1253,380],{"class":352},[329,1255,909],{"class":383},[329,1257,990],{"class":352},[329,1259,913],{"class":383},[329,1261,990],{"class":352},[329,1263,917],{"class":383},[329,1265,999],{"class":352},[329,1267,1002],{"class":383},[329,1269,387],{"class":352},[329,1271,1272,1274,1276,1278],{"class":331,"line":417},[329,1273,394],{"class":393},[329,1275,1011],{"class":352},[329,1277,400],{"class":335},[329,1279,1016],{"class":352},[329,1281,1282,1284,1286,1288],{"class":331,"line":426},[329,1283,394],{"class":393},[329,1285,1023],{"class":352},[329,1287,400],{"class":335},[329,1289,1028],{"class":352},[329,1291,1292,1294,1296,1298],{"class":331,"line":440},[329,1293,394],{"class":393},[329,1295,1035],{"class":352},[329,1297,400],{"class":335},[329,1299,1040],{"class":352},[329,1301,1302,1304,1306,1308],{"class":331,"line":448},[329,1303,394],{"class":393},[329,1305,1047],{"class":352},[329,1307,400],{"class":335},[329,1309,1052],{"class":352},[329,1311,1312],{"class":331,"line":455},[329,1313,409],{"class":352},[329,1315,1316],{"class":331,"line":467},[329,1317,369],{"emptyLinePlaceholder":368},[329,1319,1320,1322],{"class":331,"line":510},[329,1321,420],{"class":352},[329,1323,423],{"class":335},[329,1325,1326,1328,1330,1332],{"class":331,"line":530},[329,1327,375],{"class":335},[329,1329,431],{"class":335},[329,1331,434],{"class":342},[329,1333,437],{"class":352},[329,1335,1336,1338],{"class":331,"line":547},[329,1337,443],{"class":335},[329,1339,353],{"class":352},[329,1341,1342,1344,1346,1348],{"class":331,"line":558},[329,1343,1087],{"class":335},[329,1345,675],{"class":352},[329,1347,773],{"class":393},[329,1349,387],{"class":352},[329,1351,1352,1354,1356,1358],{"class":331,"line":568},[329,1353,1147],{"class":352},[329,1355,461],{"class":342},[329,1357,1103],{"class":352},[329,1359,1360],{"class":451},"\u002F\u002F Esperar a que haya elementos en el buffer\n",[329,1362,1363,1365,1367,1369],{"class":331,"line":574},[329,1364,1111],{"class":352},[329,1366,461],{"class":342},[329,1368,1103],{"class":352},[329,1370,1118],{"class":451},[329,1372,1373,1375,1378,1380],{"class":331,"line":584},[329,1374,1123],{"class":352},[329,1376,1377],{"class":342},"remove",[329,1379,1103],{"class":352},[329,1381,1382],{"class":451},"\u002F\u002F Eliminar un elemento del buffer\n",[329,1384,1385,1387,1389,1391],{"class":331,"line":590},[329,1386,1111],{"class":352},[329,1388,579],{"class":342},[329,1390,1103],{"class":352},[329,1392,1142],{"class":451},[329,1394,1395,1397,1399,1401],{"class":331,"line":595},[329,1396,1098],{"class":352},[329,1398,579],{"class":342},[329,1400,1103],{"class":352},[329,1402,1403],{"class":451},"\u002F\u002F Incrementar el contador de espacios vacíos en el buffer\n",[329,1405,1406],{"class":331,"line":1157},[329,1407,1160],{"class":352},[329,1409,1410,1412,1414,1416,1418],{"class":331,"line":1163},[329,1411,533],{"class":352},[329,1413,536],{"class":335},[329,1415,539],{"class":352},[329,1417,542],{"class":383},[329,1419,387],{"class":352},[329,1421,1422,1424,1426],{"class":331,"line":1176},[329,1423,550],{"class":352},[329,1425,553],{"class":342},[329,1427,464],{"class":352},[329,1429,1430],{"class":331,"line":1185},[329,1431,587],{"class":352},[329,1433,1434],{"class":331,"line":1190},[329,1435,409],{"class":352},[329,1437,1438],{"class":331,"line":1195},[329,1439,598],{"class":352},[304,1441,601,1442,1445,1446,1449],{},[311,1443,1444],{},"Producer"," representa a los productores que generan datos y los agregan al buffer compartido, mientras que la clase ",[311,1447,1448],{},"Consumer"," representa a los consumidores que consumen los datos del buffer. Los semáforos se utilizan para sincronizar el acceso al buffer y garantizar que los productores y consumidores trabajen de manera coordinada.",[739,1451,1453],{"id":1452},"semáforos-binarios","Semáforos Binarios",[304,1455,1456,1457,1459],{},"Un semáforo binario es un tipo especial de semáforo que solo tiene dos estados: 0 y 1. Se utiliza para implementar exclusión mutua, donde solo un hilo puede acceder a un recurso compartido en un momento dado. Un semáforo binario se puede crear utilizando la clase ",[311,1458,313],{}," con un solo permiso:",[320,1461,1463],{"className":322,"code":1462,"language":324,"meta":325,"style":325},"Semaphore binarySemaphore = new Semaphore(1); \u002F\u002F Semáforo binario\n",[311,1464,1465],{"__ignoreMap":325},[329,1466,1467,1470,1472,1474,1476,1478,1480,1482],{"class":331,"line":332},[329,1468,1469],{"class":352},"Semaphore binarySemaphore ",[329,1471,400],{"class":335},[329,1473,650],{"class":335},[329,1475,653],{"class":342},[329,1477,476],{"class":352},[329,1479,823],{"class":393},[329,1481,524],{"class":352},[329,1483,1484],{"class":451},"\u002F\u002F Semáforo binario\n",[304,1486,1487,1488,1491],{},"En este caso, el semáforo ",[311,1489,1490],{},"binarySemaphore"," se comportará como un semáforo binario, permitiendo que solo un hilo acceda al recurso compartido a la vez.",[739,1493,1495],{"id":1494},"semáforos-fuertes-y-débiles","Semáforos Fuertes y Débiles",[304,1497,1498,1499,1501,1502,1505,1506,1509,1510,1512],{},"Los semáforos pueden ser fuertes o débiles dependiendo de cómo se manejen los hilos que intentan adquirir permisos. Un semáforo fuerte garantiza que los hilos adquieran permisos en el orden en que los solicitaron, mientras que un semáforo débil no garantiza ningún orden específico. En Java, la clase ",[311,1500,313],{}," implementa un semáforo fuerte por defecto, pero también se puede crear un semáforo débil utilizando el constructor ",[311,1503,1504],{},"Semaphore(int permits, boolean fair)"," con el parámetro ",[311,1507,1508],{},"fair"," establecido en ",[311,1511,777],{},".",[320,1514,1516],{"className":322,"code":1515,"language":324,"meta":325,"style":325},"Semaphore weakSemaphore = new Semaphore(3, false); \u002F\u002F Semáforo débil\n",[311,1517,1518],{"__ignoreMap":325},[329,1519,1520,1523,1525,1527,1529,1531,1533,1536,1538,1540],{"class":331,"line":332},[329,1521,1522],{"class":352},"Semaphore weakSemaphore ",[329,1524,400],{"class":335},[329,1526,650],{"class":335},[329,1528,653],{"class":342},[329,1530,476],{"class":352},[329,1532,658],{"class":393},[329,1534,1535],{"class":352},", ",[329,1537,777],{"class":393},[329,1539,524],{"class":352},[329,1541,1542],{"class":451},"\u002F\u002F Semáforo débil\n",[304,1544,1487,1545,1548],{},[311,1546,1547],{},"weakSemaphore"," se comportará como un semáforo débil, lo que significa que los hilos pueden adquirir permisos en cualquier orden, sin garantizar un orden específico.",[739,1550,1552],{"id":1551},"semáforos-y-barreras-de-sincronización","Semáforos y Barreras de Sincronización",[304,1554,1555],{},"Una barrera de sincronización es un mecanismo que permite que un grupo de hilos se sincronice en un punto específico de su ejecución. Los semáforos se pueden utilizar para implementar barreras de sincronización, donde los hilos deben esperar hasta que todos los hilos hayan alcanzado la barrera antes de continuar con su ejecución.",[320,1557,1559],{"className":322,"code":1558,"language":324,"meta":325,"style":325},"public class Barrier {\n    private int count = 0;\n    private int totalThreads;\n    private Semaphore mutex = new Semaphore(1);\n    private Semaphore barrier = new Semaphore(0);\n    \n    public Barrier(int totalThreads) {\n        this.totalThreads = totalThreads;\n    }\n    \n    public void await() throws InterruptedException {\n        mutex.acquire();\n        count++;\n        if (count == totalThreads) {\n            barrier.release(totalThreads); \u002F\u002F Liberar a todos los hilos en la barrera\n        }\n        mutex.release();\n        barrier.acquire(); \u002F\u002F Esperar a que todos los hilos lleguen a la barrera\n    }\n}\n",[311,1560,1561,1572,1589,1598,1617,1636,1641,1656,1667,1671,1675,1692,1701,1710,1724,1737,1741,1749,1761,1765],{"__ignoreMap":325},[329,1562,1563,1565,1567,1570],{"class":331,"line":332},[329,1564,336],{"class":335},[329,1566,339],{"class":335},[329,1568,1569],{"class":342}," Barrier",[329,1571,353],{"class":352},[329,1573,1574,1576,1579,1582,1584,1586],{"class":331,"line":356},[329,1575,359],{"class":335},[329,1577,1578],{"class":335}," int",[329,1580,1581],{"class":352}," count ",[329,1583,400],{"class":335},[329,1585,686],{"class":393},[329,1587,1588],{"class":352},";\n",[329,1590,1591,1593,1595],{"class":331,"line":365},[329,1592,359],{"class":335},[329,1594,1578],{"class":335},[329,1596,1597],{"class":352}," totalThreads;\n",[329,1599,1600,1602,1605,1607,1609,1611,1613,1615],{"class":331,"line":372},[329,1601,359],{"class":335},[329,1603,1604],{"class":352}," Semaphore mutex ",[329,1606,400],{"class":335},[329,1608,650],{"class":335},[329,1610,653],{"class":342},[329,1612,476],{"class":352},[329,1614,823],{"class":393},[329,1616,507],{"class":352},[329,1618,1619,1621,1624,1626,1628,1630,1632,1634],{"class":331,"line":390},[329,1620,359],{"class":335},[329,1622,1623],{"class":352}," Semaphore barrier ",[329,1625,400],{"class":335},[329,1627,650],{"class":335},[329,1629,653],{"class":342},[329,1631,476],{"class":352},[329,1633,880],{"class":393},[329,1635,507],{"class":352},[329,1637,1638],{"class":331,"line":406},[329,1639,1640],{"class":352},"    \n",[329,1642,1643,1645,1647,1649,1651,1654],{"class":331,"line":412},[329,1644,375],{"class":335},[329,1646,1569],{"class":342},[329,1648,476],{"class":352},[329,1650,678],{"class":335},[329,1652,1653],{"class":383}," totalThreads",[329,1655,387],{"class":352},[329,1657,1658,1660,1663,1665],{"class":331,"line":417},[329,1659,394],{"class":393},[329,1661,1662],{"class":352},".totalThreads ",[329,1664,400],{"class":335},[329,1666,1597],{"class":352},[329,1668,1669],{"class":331,"line":426},[329,1670,409],{"class":352},[329,1672,1673],{"class":331,"line":440},[329,1674,1640],{"class":352},[329,1676,1677,1679,1681,1684,1686,1689],{"class":331,"line":448},[329,1678,375],{"class":335},[329,1680,431],{"class":335},[329,1682,1683],{"class":342}," await",[329,1685,498],{"class":352},[329,1687,1688],{"class":335},"throws",[329,1690,1691],{"class":352}," InterruptedException {\n",[329,1693,1694,1697,1699],{"class":331,"line":455},[329,1695,1696],{"class":352},"        mutex.",[329,1698,461],{"class":342},[329,1700,464],{"class":352},[329,1702,1703,1706,1708],{"class":331,"line":467},[329,1704,1705],{"class":352},"        count",[329,1707,701],{"class":335},[329,1709,1588],{"class":352},[329,1711,1712,1715,1718,1721],{"class":331,"line":510},[329,1713,1714],{"class":335},"        if",[329,1716,1717],{"class":352}," (count ",[329,1719,1720],{"class":335},"==",[329,1722,1723],{"class":352}," totalThreads) {\n",[329,1725,1726,1729,1731,1734],{"class":331,"line":530},[329,1727,1728],{"class":352},"            barrier.",[329,1730,579],{"class":342},[329,1732,1733],{"class":352},"(totalThreads); ",[329,1735,1736],{"class":451},"\u002F\u002F Liberar a todos los hilos en la barrera\n",[329,1738,1739],{"class":331,"line":547},[329,1740,587],{"class":352},[329,1742,1743,1745,1747],{"class":331,"line":558},[329,1744,1696],{"class":352},[329,1746,579],{"class":342},[329,1748,464],{"class":352},[329,1750,1751,1754,1756,1758],{"class":331,"line":568},[329,1752,1753],{"class":352},"        barrier.",[329,1755,461],{"class":342},[329,1757,1103],{"class":352},[329,1759,1760],{"class":451},"\u002F\u002F Esperar a que todos los hilos lleguen a la barrera\n",[329,1762,1763],{"class":331,"line":574},[329,1764,409],{"class":352},[329,1766,1767],{"class":331,"line":584},[329,1768,598],{"class":352},[304,1770,601,1771,1774,1775,1778,1779,1782],{},[311,1772,1773],{},"Barrier"," implementa una barrera de sincronización utilizando semáforos. El método ",[311,1776,1777],{},"await()"," se llama por cada hilo que llega a la barrera, y el semáforo ",[311,1780,1781],{},"barrier"," se libera solo cuando todos los hilos han llegado a la barrera, lo que permite que todos los hilos continúen con su ejecución.",[739,1784,1786],{"id":1785},"conclusión","Conclusión",[304,1788,1789],{},"Los semáforos son una herramienta poderosa para controlar el acceso a recursos compartidos en la programación concurrente. Al utilizar semáforos, podemos evitar condiciones de carrera y garantizar que los hilos accedan a los recursos de manera segura y coordinada. Es importante entender cómo funcionan los semáforos y cómo utilizarlos correctamente para evitar problemas de sincronización en nuestras aplicaciones concurrentes.",[1791,1792,1793],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}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 .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}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":325,"searchDepth":356,"depth":356,"links":1795},[1796,1797,1798,1799,1800,1801,1802,1803],{"id":741,"depth":356,"text":742},{"id":798,"depth":356,"text":799},{"id":834,"depth":356,"text":835},{"id":921,"depth":356,"text":922},{"id":1452,"depth":356,"text":1453},{"id":1494,"depth":356,"text":1495},{"id":1551,"depth":356,"text":1552},{"id":1785,"depth":356,"text":1786},"En este artículo se explicará qué son los semáforos en Java, cómo funcionan y cómo se pueden utilizar para controlar el acceso a recursos compartidos en la programación concurrente.","md",null,{"editButton":104},{"icon":83},{"title":137,"description":1804},"Afl6vmmDXO1S2LqJKvvb5n6VHWeMlCCvVxYs8ij1jCs",[1812,1814],{"title":133,"path":134,"stem":135,"description":1813,"icon":83,"children":-1},"En este artículo se explicará cómo emular condiciones 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.",{"title":141,"path":142,"stem":143,"description":1815,"icon":83,"children":-1},"En este artículo se explicará cómo utilizar la clase Timer en Java Swing para programar tareas que se ejecuten después de un cierto retraso o de forma periódica, lo que es útil para crear interfaces de usuario dinámicas y reactivas.",1775101373006]