2010-12-13 25 views
23

Parece que he cometido un error con Java Threads/OS Threads and Interpreted language.Hilos Java vs Hilos OS

Antes de comenzar, entiendo que Green Threads son Java Threads, donde JVM se ocupa de los hilos y todo el proceso de Java se ejecuta solo como un único subproceso del sistema operativo. Por lo tanto, en un sistema de procesador múltiple es inútil.

Ahora mis preguntas son. Tengo dos hilos A y B. Cada uno con 100 mil líneas de código independiente. Ejecuto estos hilos en mi Programa Java en un sistema multiprocesador. Cada subproceso recibirá un subproceso del SO nativo para ejecutar que se puede ejecutar en una CPU diferente, pero desde que se interpreta, estos hilos requerirán interactuar con la JVM una y otra vez para convertir el código de bytes en instrucciones de la máquina. ¿Estoy en lo cierto? En caso afirmativo, que para programas más pequeños, ¿Java Threads no será una gran ventaja?

Una vez que el Hotspot compila ambas rutas de ejecución, ambas pueden ser tan buenas como las Threads nativas. ¿Estoy en lo cierto?

[EDITAR]: Una pregunta alternativa puede ser, suponga que tiene un solo subproceso de Java cuyo código no está compilado JIT, usted crea ese subproceso y lo inicia()? ¿Cómo interactúan el subproceso del sistema operativo y JVM para ejecutar ese bytecode?

gracias

Respuesta

25

cada hilo se dará un nativo hebra del sistema operativo a RUN que se puede ejecutar en una CPU diferente pero desde Java es interpreta estos hilos requerirán para interactuar con la JVM de nuevo y de nuevo para convertir el byte código a instrucciones de la máquina? ¿Estoy en lo cierto?

Estás mezclando dos cosas diferentes; JIT realizado por la VM y el soporte de subprocesamiento ofrecido por la VM. En el fondo, todo lo que haces se traduce a algún tipo de código nativo. Una instrucción de código de bytes que utiliza el hilo no es diferente de un código JIT que accede a los hilos.

En caso afirmativo, que para programas pequeños Java ¿Los hilos no son una gran ventaja?

Define small aquí. Para procesos de corta vida, sí, el enhebrar no hace una gran diferencia ya que su ejecución secuencial es lo suficientemente rápida. Tenga en cuenta que esto nuevamente depende del problema que se está resolviendo. Para los kits de herramientas de interfaz de usuario, no importa qué tan pequeña sea la aplicación, se requiere algún tipo de ejecución de subprocesamiento/asincrónica para mantener la UI receptiva.

Enhebrar también tiene sentido cuando tiene cosas que pueden se pueden ejecutar en paralelo. Un ejemplo típico sería hacer IO pesado en el hilo y cómputo en otro. Realmente no querrás bloquear tu procesamiento solo porque tu hilo principal está bloqueado haciendo IO.

Una vez que el hotspot compila estas dos rutas de ejecución ambos pueden ser tan buenos como subprocesos nativos? ¿Estoy en lo cierto?

Ver mi primer punto.

Enlazar realmente no es una bala de plata, especialmente cuando se trata del concepto erróneo común de "usar hilos para hacer que este código sea más rápido". Un poco de lectura y experiencia será tu mejor apuesta. ¿Puedo recomendar una copia de this awesome book? :-)

@Sanjay: Infact ahora puedo replantear mi pregunta . Si tengo un hilo cuyo código no ha sido JIT, ¿cómo lo ejecuta el subproceso OS ?

Nuevamente lo digo, enhebrar es un concepto completamente diferente de JIT. Vamos a tratar de mirar a la ejecución de un programa en términos simples:

pkg.MyClass Java -> VM localiza método a ejecutar -> Iniciar la ejecución de la código de bytes para la línea por línea método -> convertir cada instrucción de código byte a su contraparte nativa -> instrucciones ejecutado por OS -> instrucción ejecutada por la máquina

Cuando JIT ha pateado en:

java pkg.MiClase -> VM localiza método que se ejecute que ha sido JIT'ed -> localizar el código asociado nativa para ese método -> instrucciones ejecutado por OS -> instrucción ejecutada por la máquina

Como puede ver, independientemente de la ruta que siga, la instrucción VM debe asignarse a su contraparte nativa en algún momento. Si ese código nativo se almacena para su reutilización o si se desecha si es diferente (optimización, ¿recuerdas?).

ahí para responder a su pregunta, cada vez que se escribe enhebrar código, es traducido a código nativo y ejecutar por el sistema operativo. Si la traducción se hace sobre la marcha o se busca en ese punto en el tiempo es un problema completamente diferente.

+0

Lo siento por la diatriba, esta respuesta fue mucho más larga de lo esperado. ;-) –

+0

@Sanjay: Si lo hago bien, JIT se realizará incluso antes de que el subproceso se ejecute por primera vez.Esencialmente, la JVM primero hace el JIT para ambos hilos independientes y luego los envía a los hilos del sistema operativo para su ejecución. – Geek

+1

@ Geek: como ya se mencionó, JIT y la ejecución de subprocesos son dos cuestiones ortogonales. Sí, es muy posible que la pieza de código que un subproceso está a punto de ejecutarse ya haya sido JIT por la máquina virtual. Además, no hay * reenvío * de ejecución. Cuando se invoca un método 'start()' en un objeto Thread, se crea un nuevo hilo nativo del sistema operativo, no hay reenvío entre "hilo Java" y "hilo OS". Además, JIT no es obligatorio. Puede suceder que su hilo esté ejecutando código que no ha sido JIT. JIT es una optimización específica del rendimiento. –

7

y todo el proceso de Java sólo se ejecuta como una sola hebra del sistema operativo

Esto no es cierto. Por lo tanto, no especificado, a menudo vemos que los hilos de Java son, de hecho, subprocesos nativos del sistema operativo y que las aplicaciones de multiproceso de Java realmente hacen uso de procesadores multi-core o plataformas multiprocesador.

Una recomendación común es usar un grupo de subprocesos donde el número de subprocesos es proporcional al número de núcleos (factor 1-1.5). Esta es otra sugerencia, que la JVM no está restringida a un solo proceso/subproceso del sistema operativo.


De Wkipedia:

En Java 1.1, hilos verdes fueron el único modelo de subprocesamiento utilizado por la JVM, [4] por lo menos en Solaris. Como los subprocesos verdes tienen algunas limitaciones en comparación con los subprocesos nativos, versiones subsiguientes de Java los descartaron en favor de los subprocesos nativos.

Ahora, en 2010 con Java 7 en desarrollo y Java 8 planeado, ¿estamos realmente interesados ​​en los "hilos verdes" históricos?

+0

Estaba hablando solo de Threads específicos anteriores a JDK i.2 conocidos como Green Threads. – Geek

+0

@Geek - "mencionaste" hilos verdes, pero tu pregunta fue (mirando el título) sobre los hilos de Java en general. Edite su pregunta, si solo le interesan los hilos verdes y Java 1.1/1.2 –

+0

Claro. En realidad, en el caso de Green Threads es fácil entender cómo la JVM maneja la conversión de código Byte cuando ejecuta dos hilos porque la JVM tiene el control completo. No puedo entenderlo en caso de que los dos hilos se ejecuten como subprocesos del sistema operativo. – Geek

2

Enhebrar y ejecutar un código de bytes son cuestiones independientes. Hilos verdes son utilizados por JVM en plataformas que no tienen soporte nativo de hilos. (En mi humilde opinión, no sé qué plataforma no admite subprocesos).

El código de byte se interpreta en tiempo real y se ejecuta en la plataforma nativa por JVM. JVM decide cuáles son los fragmentos de código más populares y realiza la llamada compilación Just-in-time de estos fragmentos, por lo que no tiene que compilarlos una y otra vez. Esto es independiente de enhebrar. Si, por ejemplo, tiene un hilo que ejecuta el mismo fragmento de código en el bucle, este fragmento se almacenará en caché por compilador justo a tiempo.

En pocas palabras: no se preocupe por el rendimiento y los hilos. Java es lo suficientemente fuerte como para ejecutar todo lo que está codificando.

+0

Java 1.0 en Solaris usó hilos verdes. No estoy seguro de que alguien lo haya hecho desde entonces, pero está permitido en el diseño. –

+0

Así que, como dijo si tengo todo el código de JIT o a través del punto de acceso, puedo ejecutar efectivamente dos hilos de Java como dos hilos de sistema operativo, lo suficiente. Pero creo que la compilación de JIT ocurre en la primera pasada del código, así que la primera vez que ejecuto el código que inicia dos hilos, los dos hilos aún tendrán que ser interpretados. Por lo tanto, JVM estará involucrado por ambos hilos del sistema operativo. – Geek

+0

Por lo que sé, JVM crea una capa delgada sobre el hilo nativo. Todos los subprocesos de una aplicación comparten la misma memoria, por lo que el código compilado con el código nativo se compartirá entre subprocesos. – AlexR

3
  1. Algunos Java-implementaciones pueden crear hilos verdes como lo describes (programación realizado por la JVM en un único subproceso nativo ), pero lo normal implementaciones de Java en el uso de PC múltiples núcleos.
  2. La propia JVM podría ya usar diferentes subprocesos para el trabajo a realizar (recolección de basura, carga de clases, verificación de código de bytes, compilador JIT).
  3. El sistema operativo ejecuta un programa llamado JVM. La JVM ejecuta el Java-Bytecode. Si cada subproceso de Java tiene un subproceso nativo asociado (que tiene sentido y parece ser el caso en las implementaciones de PC), entonces el código de JVM en ese subproceso ejecuta el código de Java - JITed o interpretado - como en un solo subproceso -programa. No hay diferencia aquí a través de multihilo.