Programación General > Java
Calcular Retardos
jpaler:
Hola muchachos !!!!
...,¿alguno de ustedes sabe como obtener la velocidad del procesador
en java?
...,¿y sabe mas o menos como calcular un retardo basado en milisegundos
a partir de esa velocidad?
---------------------------------------------
es q tengo un inconveniente al calcular los retardos de manera comun y
corriente como estos deberia ser calculados, miren:
--- Código: Text --- public void delay(long timeOut){ while ( ( timeOut > 0 ) && ( puertoSerial.estaOcupado() ) ) { try { Thread.sleep( 10 ); //this.wait(10); } catch ( InterruptedException e ) {} timeOut--; } return; }
con este metodo, si yo le mandara: delay(100);
me deberia esperar un tiempo maximo de 1 seg. antes de retornar.
o menos tiempo, en caso de q el puerto serial se desocupe antes de 1 seg.
...,pero no, no espera nada, es como si el metodo sleep/wait no cumpliera
su funcion.
alguien me dijo q era por la prioridad q el propio compilador le da a los
ciclos (for, while, do-while), osea, q como esta dentro de un while, la
jvm nisiquiera me determina el sleep y simplemente se dedica a seguir el ciclo.
y le creo, por q no es la primera ves q me pasa, tambien he intentado
hacer q se actualize un JProgresssBar dentro de un ciclo (poniendo un retardo)
y tampoco la actualiza, lo q hace es terminar el ciclo y luego pinta el JProgressBar.
NO ES ESTO ALGO RARO.
--------------------------------
entonces, he decidido calcular yo mismo los retardos a razon de la
velocidad del procesador y basandome en ciclos repetitivos.
les agradeceria cualquiera idea q tengan sobre esto.
--------------------------------
Gracias....
silverfox:
Hola a todos.
Creo recordar que Java no tiene forma de encontrar el procesador, puesto que no está en las propiedades del sistema. La opción que tienes es preguntárselo al SO y obtenerlo con un método nativo.
De todas formas, estás equivocado en una cuestión:
--- Código: Text ---Thread.sleep( 10 );
El parámetro de este método está dado en milisegundos, por lo que, si quieres que espere un segundo, tendrás que utilizar sleep(1000).
Yo lo que haría sería otra cosa, ya que estás implementando una espera activa con el sleep y eso baja el rendimiento de tu aplicación.
Utiliza mejor el wait() que tienes comentado. Lo único que tienes que hacer es meter una instrucción notify() o notifyAll() justo antes de la salida del método que se ejecute cuando el puertoSerie quede libre. Los métodos donde tengas el wait y el notify deberían ser synchronized, con eso tendrías que poder manejar la variable puertoSerie de forma exclusiva sin problemas.
Espero que consigas resolverlo. Si tienes más dudas, ya sabes.
Un saludo.
Silverfox
jpaler:
silver, me inclino mas por la segunda solucion q me das, aunque no la
comprendo mucho:
--- Código: Text --- Yo lo que haría sería otra cosa, ya que estás implementando una espera activa con el sleep y eso baja el rendimiento de tu aplicación.Utiliza mejor el wait() que tienes comentado. Lo único que tienes que hacer es meter una instrucción notify() o notifyAll() justo antes de la salida del método que se ejecute cuando el puertoSerie quede libre. Los métodos donde tengas el wait y el notify deberían ser synchronized, con eso tendrías que poder manejar la variable puertoSerie de forma exclusiva sin problemas.
...silver, mi programa debe funcionar asi:
tengo 2 metodos, uno q lee del puerto serial y otro q escribe en el puerto serial.
ambos metodos llaman SIEMPRE a delay y le mandan un parametro tiempo.
y el metodo delay debe RETORNAR UNICAMENTE cuando el puerto serial este
LIBRE, o haya TRANSCURRIDO el tiempo maximo pasado como parametro.
...UNICAMENTE ASI DEBERA DELAY RETORNAR, MIENTRAS TANTO NO.
Y es eso lo q he intentado hacer con la funcion delay(long timeOut).
...compadre, ¿seria posible q usted me explicara como funciona el wait/notify o las diferencias de este con el sleep?
...y me explicaras mejor la solucion q me propones?
GRACIAS SILVER !!!
silverfox:
Con gusto, jpaler. Vamos a ver...
Si quieres echar un vistazo extenso a estas cosas, mira en algún libro el trabajo con Threads.
Para empezar, supongo que sabes lo que ocurre con un método sincronizado en Java: Cuando llamas a un método clasificado como synchronized, se bloquearán todas las llamadas posteriores a métodos synchronized del mismo objeto por parte de otras hebras. Este bloqueo termina cuando el Thread que llamó retorna del método sincronizado, dejando el camino libre a una de las hebras que entrará en uno de los métodos sincronizados del objeto compartido.
Cuando se hace un sleep, la hebra que llama al método queda ocupando el método, a diferencia de cuando se llama a wait. En el último caso, la hebra queda en estado de suspendida (puedes ver el método suspend de Thread, también deberías repasar el ciclo de vida de una hebra en Java en la documentación o en algún libro similar). Por lo tanto, si usas sleep, puede que la máquina virtual continúe ejecutando la hebra dormida y que, por lo tanto, la otra no avance (con un tiempo de sleep tan corto como ponías en tu ejemplo, seguramente haya pasado eso).
Tal y como lo pones, creo que la opción sería la siguiente:
--- Código: Text ---public synchronized void delay(long timeOut){ while (puertoSerial.estaOcupado()){ this.wait(timeOut); } return;}
pero también tendrás que modificar los métodos que modifiquen la variable ocupado:
--- Código: Text ---public synchronized void setOcupado(boolean busy){ this.ocupado= busy; if (!busy) this.notifyAll();}
Cuando se hace el wait, quedarás bloqueado en el método, en espera de que alguien te despierte con un notify. El wait con un parámetro indica un tiempo de espera en milisegundos. Si no se recibe el notify correspondiente en este tiempo, la hebra despertará sola y continuará la ejecución.
Si sólo tienes 2 hebras, en lugar de un while, podrás poner un if y te dará el comportamiento que esperabas. Si tienes más de dos hebras funcionando deberás usar el while, considerando que el notifyAll despierta a todas las hebras que estén dormidas en el wait, pero de las cuales sólo una podrá entrar en el método, las otras tendrían que volver a ejecutar el wait (por eso el while).
Espero que con estos consejos puedas terminar el trabajo sin problemas. Si necesitas alguna cosa más, ya sabes.
Un saludo.
Silverfox
jpaler:
bueno silver.... dejame y doy un respiro y compilo en mi pequeña
mente todo lo q me dijiste...
...¿acaso eres profesor?
sabes explicar muy bien...
Gracias por todo ese monton de info q me acabas de dar....
...,voy a codificar algo de lo q dices y luego te comento listo !!!
Navegación
[#] Página Siguiente
Ir a la versión completa