{"id":2899,"date":"2018-03-11T02:16:18","date_gmt":"2018-03-11T07:16:18","guid":{"rendered":"https:\/\/www.manualjava.net\/?p=2899"},"modified":"2018-03-12T17:33:04","modified_gmt":"2018-03-12T22:33:04","slug":"prioridad-entre-hilos","status":"publish","type":"post","link":"https:\/\/www.manualjava.net\/?p=2899","title":{"rendered":"Prioridad entre hilos"},"content":{"rendered":"<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-2902\" src=\"https:\/\/www.manualjava.net\/wp-content\/uploads\/2018\/03\/java49-300x83.png\" alt=\"\" width=\"292\" height=\"81\" srcset=\"https:\/\/www.manualjava.net\/wp-content\/uploads\/2018\/03\/java49-300x83.png 300w, https:\/\/www.manualjava.net\/wp-content\/uploads\/2018\/03\/java49.png 324w\" sizes=\"(max-width: 292px) 100vw, 292px\" \/><\/p>\n<p><span style=\"color: #000000;\">Los sistemas operativos difieren en la forma de planificar la ejecuci\u00f3n de los hilos. Windows gestiona el reparto de los tiempos de ejecuci\u00f3n de los hilos (tareas) de forma directamente proporcional a la prioridad asignada a cada hilo.\u00a0<\/span><!--more--><\/p>\n<p><span style=\"color: #000000;\">Ello significa la concesi\u00f3n de una cantidad de tiempo de ejecuci\u00f3n a un hilo; finalizado ese tiempo el sistema concede la ejecuci\u00f3n a otro hilo. As\u00ed, de forma circular el sistema va asignando los tiempos de CPU a los hilos, con mayor tiempo a los hilos con mayor prioridad. De esta forma, los hilos con mayor prioridad se ejecutan primero, ya que proporcionalmente se les asigna mayor tiempo de ejecuci\u00f3n. Esto no significa que un hilo con mayor prioridad se ejecute hasta terminar, sino que los tiempos de CPU se reparten proporcionalmente seg\u00fan la prioridad que tengan. Hay que tener en cuenta que un hilo, aunque tenga mayor prioridad, pierde el control de la ejecuci\u00f3n si efect\u00faa una llamada a sleep(); tambi\u00e9n puede ceder ese control si llama a yield().<\/span><\/p>\n<p><span style=\"color: #000000;\">Java asigna, por omisi\u00f3n, la prioridad 5 (Thread.NORM_PRIORITY) a un hilo cuando este se crea. El rango de valores de la prioridad est\u00e1 determinado por las constantes: Thread.MIN_PRIORITY, Thread.MAX_PRIORITY. La prioridad de un hilo se puede modificar con el m\u00e9todo de la clase Thread:<\/span><\/p>\n<p><span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0public final void setPriority(int prioridad)<\/span><\/p>\n<p><span style=\"color: #000000;\">Para obtener la prioridad de un hilo se utiliza el m\u00e9todo de Thread:<\/span><\/p>\n<p><span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0public final int getPriority()<\/span><\/p>\n<p><span style=\"color: #000000;\">Por razones de seguridad, no se permite a un applet modificar la prioridad de un hilo.<\/span><\/p>\n<h2><strong><span style=\"color: #000000;\"><span style=\"color: #000000;\">Hilos daemon<\/span><\/span><\/strong><\/h2>\n<p><span style=\"color: #000000;\">Un hilo \u00abdemonio\u00bb tiene como prop\u00f3sito realizar servicios a otros hilos de ejecuci\u00f3n. Los hilos demonio finalizan cuando todos los hilos \u00abno demonio\u00bb finalizan, o bien cuando termina el m\u00e9todo run() asociado. El ejemplo t\u00edpico de hilo demonio es el \u00abrecolector de basura\u00bb (garbage collection), el cual se ejecuta en paralelo con el resto de hilos de la aplicaci\u00f3n. El m\u00e9todo, de la clase Thread, setDaemon() aplicado a un hilo, con el argumento true, despu\u00e9s de su creaci\u00f3n lo define como demonio.<\/span><\/p>\n<h3><span style=\"color: #000000;\"><strong>Ejemplo<\/strong><\/span><\/h3>\n<p><span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0Thread hilo = new ClaseHilo();<\/span><br \/>\n<span style=\"color: #000000;\"> \u00a0 \u00a0 \u00a0 \u00a0 hilo.setDaemon(true);<\/span><\/p>\n<p><span style=\"color: #000000;\">Un \u00abdemonio\u00bb se puede considerar un hilo de servicio. Su existencia es para suministrar alg\u00fan tipo de servicio a otros hilos, por eso si los hilos a los que dan servicio desaparecen, tambi\u00e9n desaparecen los demonios.<\/span><\/p>\n<h2><span style=\"color: #000000;\"><strong>Sincronizaci\u00f3n<\/strong><\/span><\/h2>\n<p><span style=\"color: #000000;\">En las aplicaciones es normal que existan muchos hilos en ejecuci\u00f3n. Es posible que varios de ellos deseen modificar el mismo objeto al mismo tiempo; en este caso es necesario sincronizarlos. Por ejemplo, en una aplicaci\u00f3n por internet de reservas de entradas para una \u00f3pera, dos hilos tratan de reservar simult\u00e1neamente el palco 5; se puede producir una situaci\u00f3n no deseada, a los dos hilos se les est\u00e1 ofreciendo como libre el palco, si no se sincronizan los dos hilos se llevar\u00edan dicho palco. Otra situaci\u00f3n que hace necesaria la sincronizaci\u00f3n es cuando un hilo debe esperar datos proporcionados por otro hilo.<\/span><\/p>\n<p><span style=\"color: #000000;\"><span style=\"color: #000000;\">Para solucionar este tipo de problemas se sincronizan los procesos. Los bloques de c\u00f3digo que acceden a un mismo recurso (un objeto, un archivo, . . .) desde dos o m\u00e1s hilos constituyen secciones cr\u00edticas. Para marcar secciones cr\u00edticas se utiliza el modificador\u00a0<strong>synchronized.\u00a0<\/strong>Por ejemplo:<\/span><\/span><\/p>\n<p><span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 public synchronized void asignarSeat(int n, char s){<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0while(condici\u00f3n){<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0sentencias;<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0}<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 }<\/span><\/p>\n<p><span style=\"color: #000000;\">De esta forma, durante el tiempo que un hilo ejecuta el m\u00e9todo (o bloque de c\u00f3digo) sincronizado, el recurso (objeto) queda bloqueado (en lock). Otros hilos que quieran acceder al mismo recurso se quedan a la espera de una notificaci\u00f3n (notify()) de que ha terminado el bloqueo.<\/span><\/p>\n<h3><span style=\"color: #000000;\"><strong>Ejemplo<\/strong><\/span><\/h3>\n<p><span style=\"color: #000000;\">Se dise\u00f1a una clase de gesti\u00f3n de datos. Un m\u00e9todo pone los datos en un buffer (arreglo), otro m\u00e9todo retira datos del buffer. Los dos m\u00e9todos se declaran sincronizados. La clase GestorDatos dispone de un arreglo que se crea en el constructor con un tama\u00f1o determinado por un constante (MX). El m\u00e9todo ingresarDato() asigna valores arbitrarios al buffer, el m\u00e9todo retirarDato() extrae elementos del buffer. Estos dos m\u00e9todos deben declararse sincronizados.<\/span><\/p>\n<p><span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 public class GestorDatos {<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0final static int MX=50;<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0private int datos[];<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0private int ultimo;<\/span><\/p>\n<p><span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0public GestorDatos(){<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 this.datos = new int[MX];<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ultimo = -1;<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0}<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0public synchronized void ingresarDato(int dato){<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 while(ultimo&lt;datos.length-1){<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ++ultimo;<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 datos[ultimo] = dato+2*ultimo+1;<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0}<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0public synchronized void retirarDato(){<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 int datoRetirado;<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 while(ultimo&gt;=0){<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 datoRetirado = datos[ultimo];<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u2013\u2013ultimo;<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 System.out.println(\u00abRetirado: \u00ab+ datoRetirado);<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0} <\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 }<\/span><\/p>\n<p><span style=\"color: #000000;\">Ahora suponga que la aplicaci\u00f3n dispusiera de dos hilos, uno que se encargue de ingresar datos y el otro de retirar datos:<\/span><\/p>\n<p><span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 hiloGenera.start();\u00a0 {desde run() llama a ingresarDato()}<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 hiloRetira.start();\u00a0 {desde run() llama a retirarDato()}<\/span><\/p>\n<p><span style=\"color: #000000;\">El primer hilo bloquea el objeto Dato, el otro hilo quiere acceder al mismo objeto por lo cual se queda a la espera de que quede libre (\u00absin lock\u00bb) el objeto para poder trabajar con \u00e9l.<\/span><\/p>\n<p><span style=\"color: #000000;\">Dentro de un m\u00e9todo sincronizado no se debe utilizar el m\u00e9todo sleep() debido a que el objeto se va a quedar bloqueado durante el tiempo de sleep. Se recomienda utilizar el m\u00e9todo wait() de la clase Object. El m\u00e9todo wait() detiene el hilo durante los milisegundos del argumento y lo pone en cola de espera, pero deja de bloquear al objeto. El hilo deja la cola de espera cuando acaba el tiempo, o hasta que otro hilo active el m\u00e9todo notify() (o notifyAll()) de ese mismo objeto. La declaraci\u00f3n de estos m\u00e9todos se encuentra en la clase Object:<\/span><\/p>\n<p><span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0public final void wait()<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0public final void wait(long mensaje)<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0public final void notify()<\/span><br \/>\n<span style=\"color: #000000;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0public final void notifyAll()<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Los sistemas operativos difieren en la forma de planificar la ejecuci\u00f3n de los hilos. Windows gestiona el reparto de los tiempos de ejecuci\u00f3n de los hilos (tareas) de forma directamente proporcional a la prioridad asignada a cada hilo.\u00a0<\/p><p><a class=\"more-link btn\" href=\"https:\/\/www.manualjava.net\/?p=2899\">Seguir leyendo<\/a><\/p>\n","protected":false},"author":1,"featured_media":2902,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[],"_links":{"self":[{"href":"https:\/\/www.manualjava.net\/index.php?rest_route=\/wp\/v2\/posts\/2899"}],"collection":[{"href":"https:\/\/www.manualjava.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.manualjava.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.manualjava.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.manualjava.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2899"}],"version-history":[{"count":23,"href":"https:\/\/www.manualjava.net\/index.php?rest_route=\/wp\/v2\/posts\/2899\/revisions"}],"predecessor-version":[{"id":2957,"href":"https:\/\/www.manualjava.net\/index.php?rest_route=\/wp\/v2\/posts\/2899\/revisions\/2957"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.manualjava.net\/index.php?rest_route=\/wp\/v2\/media\/2902"}],"wp:attachment":[{"href":"https:\/\/www.manualjava.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2899"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.manualjava.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2899"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.manualjava.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2899"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}