2010-09-26 7 views
9

Estoy preparando para el SCJP, y el multihilo ha sido mi área más inestable, sobre todo porque no sé cómo mirar el código multiproceso y recorrerlo. Hasta ahora, mi enfoque ha sido escribir en inglés lo que podría estar sucediendo en cada hilo y probar algunos casos con hilos que se intersectan aleatoriamente entre sí, lo que es un enfoque realmente arriesgado y lento. Entonces me gustaría ver cómo lo haría un profesional. ¿Estaría dispuesto a leer el siguiente código (es la última pregunta que me está causando problemas) y anotar lo que pasa por su cabeza (solo por cuestiones de código, por favor :) a medida que elabora los posibles resultados? Las elecciones que vienen con la pregunta son al final. Lo que estoy buscando no es la solución que tengo, sino cómo se llega a la solución de manera eficiente en el examen.¿Cómo piensas y predice el resultado de una pregunta de subprocesamiento como esta?

Y sí, sé que esta pregunta no tiene una respuesta precisa, etc, etc voto Aceptado va a la respuesta que es más claro y más fácil de imitar, bien :)

Gracias a todos!

Pregunta: ¿Cuáles de estas respuestas son salidas posibles?

public class Threads1 { 

    int x = 0; 

    class Runner implements Runnable { 

     public void run() { 
      int current = 0; 
      for (int i = 0; i < 4; i++) { 
       current = x; 
       System.out.print(current + ", "); 
       x = current + 2; 
      } 
     } 
    } 

    public static void main(String[] args) { 
     new Threads1().go(); 
    } 

    public void go() { 
     Runnable r1 = new Runner(); 
     new Thread(r1).start(); 
     new Thread(r1).start(); 
    } 
} 

opciones (elegir todo lo que corresponda):

A. 0, 2, 4, 4, 6, 8, 10, 6,

B. 0, 2, 4, 6 , 8, 10, 2, 4,

C. 0, 2, 4, 6, 8, 10, 12, 14,

D. 0, 0, 2, 2, 4, 4, 6 , 6, 8, 8, 10, 10, 12, 12, 14, 14,

E. 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14,

+0

¿Cuál es la respuesta de Anita? Me gustaría ver su respuesta antes de darle mi forma de pensar sobre el problema. – Gray

+1

La visualización es la clave, haga su propia técnica de diagramación, lo suficiente como para mostrar lo que está sucediendo al mismo tiempo y qué recursos se comparten entre cada hilo. –

+0

No respondí porque sería demasiado fácil :) En serio, una vez que sé la respuesta, puedo explicar por qué está bien, pero es averiguar qué es lo que tengo que hacer en primer lugar y no puedo hacer aún –

Respuesta

11

A y C (suponiendo que la pregunta es ¿Cuál de estas respuestas son posibles salidas?)

La parte difícil, por supuesto, no es cuando se encuentra una posible solución. Por el contrario, es difícil mirar a los que cree que son no posibles y tratar de convencerse de que tiene una razón sólida por la cual no es posible y que ha eliminado todas las formas de evitar su razón.

Hasta ahora mi enfoque ha sido escribir en Inglés lo que podría estar sucediendo en cada hilo ...

Usted que averiguar cuál de ellos impreso cada número. A continuación se muestra el formato más eficiente y sucinto que se me ocurrió representar y hacer que sea más fácil tachar/borrar/escribir mientras se trabaja en las posibilidades. Darse cuenta:

  • Una vez que encuentre una posible respuesta movimiento en. No importa si no es probable en el mundo real o si puede haber otras combinaciones posibles (o imposibles). Siempre y cuando encuentre 1 posibilidad, eso es todo lo que necesita para pasar al.

  • Pruebe primero el enfoque más simple, p. asuma T1 para cada número hasta que llegue a un número que no podría ser T1, de modo que complete T2, y así sucesivamente. Con suerte, llegará al final sin contradicción (o contradicciones que sean fáciles de resolver). Una vez que haya encontrado una combinación posible, continúe.

  • Siéntase libre de omitir eliminar los posibles rápidamente para que pueda centrarse en los probablemente imposibles.

Aquí es la edición final de mi arañazos papel/hoja de trabajo (anexo con mis anotaciones mentales):

A. 0, 2, 4, 4, 6, 8, 10, 6, 
    1 1 1 2 2 2 2 1  <- possible threads that produced this output - possible solution 

B. 0, 2, 4, 6, 8, 10, 2, 4, 
    1 2 2 2 2 ? 1  <- to print second '2', T1 interrupted between L10/L11; 4 passes of T2 used up 

C. 0, 2, 4, 6, 8, 10, 12, 14, 
    1 1 1 1 2 2 2 2 <- possible solution - simplest solution (T2 waits until T1 is completely done) - doesn't matter that it isn't likely, just that is possible 

D. 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 
    1 2 1 2 1 2 1 2 1 2 ? <- threads used up 

E. 0, 2, 4, 6, 8, 10, 12, 14, 0, 2, 4, 6, 8, 10, 12, 14, 
    1 1 1 1 2 2 2 2 ? <- threads used up 

Nota:

http://download.oracle.com/javase/tutorial/essential/concurrency/atomic.html

  • Reads y las escrituras son atómicas para las variables de referencia y para la mayoría de las variables primitivas (todas las ypes excepto largo y doble).
  • ...

acciones atómicas no pueden ser intercalados, para que puedan ser utilizados sin miedo a la interferencia de rosca.

+1

+1 Muy bien diseñado lógica – linuxuser27

+1

buen truco para resolver – Netro

+1

@BertF podemos pensar de la siguiente manera: No importa la ejecución de los hilos, debe haber más de 8 números impresos, por lo que D y E no pueden ser producidos por este ejemplo y luego usar tus pensamientos para A, B y C? – Xelian

5

Mi enfoque a los problemas de subprocesos múltiples es romper el código que ejecutará el subproceso y luego determinar cuántos subprocesos ejecutará ese código y si tiene acceso a cualquier variable que otros subprocesos podrían utilizar potencialmente.

En el ejemplo, hay 3 hilos. El hilo main llama a new Threads1().go();, crea r1 y comienza 2 hilos más, new Thread(r1).start(); y new Thread(r1).start();. Ahora que sabemos cuántos hilos podemos rastrear lo que van a hacer.

El hilo main va a morir después de que regrese de go().

Los otros 2 subprocesos entrarán en el método run() del objeto Runner, r1. Ahora lo que también sabemos es que cada hilo ejecutará run(). Así que veamos qué hace run(). Tiene un bucle for que imprime la salida cada vez que ejecuta el bucle. Por lo tanto, la llamada al run() imprimirá 4 veces. Entonces 2 hilos cada hilo imprimirá 4 veces. Por lo tanto, la salida no puede tener más de 8 números.

En cuanto a lo que esas cifras no serán realmente va a ser posible desde la instancia Runner será el mismo para cada hilo de la variable x puede cambiar en función del otro hilo que también está llamando run(). Por lo tanto, todo lo que necesita determinar es, ¿es posible la secuencia de dígitos? La respuesta a esa pregunta es 'sí' para A y C.Esto se debe al hecho de que no tiene idea de cuándo cada subproceso será reemplazado por el otro y, dado que durante el bucle se está realizando una copia local, puede obtener ordenes muy únicas.

Como se menciona a continuación por SB, la opción B, aunque tiene 8 salidas, no es posible. Intenta crear una secuencia de hilo para crear esa salida.

+2

¿Cómo es que sí para B? –

+0

Oh wow. Esa es una buena llamada. Mi error. Voy a corregir eso. Gran captura. – linuxuser27

+0

la respuesta podría ser A, B o incluso C dependiendo de qué prioridad tenga cada subproceso y cuándo se ejecute cada instrucción. Mi mejor opción sería responder A ya que es la única respuesta que muestra algunos números repetidos entrelazados, lo que significa que ambos hilos se están ejecutando en paralelo. Pero cualquiera de los primeros 3 podría estar justificado. –

0

Esta pregunta es mucho más engañosa de lo que parece, me gusta más lo pienso.Comencé mi respuesta hablando sobre cómo veo los programas de subprocesos: analizo los puntos de sincronización y las llamadas de E/S. Pero esto no tiene ninguno a excepción de la impresión que no tiene sincronización interna. Así que nos quedan tiempos aleatorios (ver race conditions). Esto combinado con una forma no garantizada de sincronizar los valores de x entre los hilos significa que será aleatorio.

Sin embargo, si miramos las respuestas, podemos ver que algunas de las respuestas no pueden ocurrir. Por ejemplo, como señaló @ linuxuser27, cada hilo imprime 4 números solamente, lo que elimina las respuestas y se imprimen más números. Otro ejemplo de una respuesta incorrecta sería si alguna de las respuestas tiene un valor mayor a 14, ya que el primer hilo puede ir 0,2,4,6 y el segundo podría llevarlo a 8,10,12,14 pero no más.

Como cada uno de los hilos debe imprimir un número de 4 tiempos y números impresos por cada hilo debe ser al menos 2 + el número anterior el hilo impreso, algunos de los patrones no puede ser generado. No daré mi respuesta pero no es 'todo lo anterior' y no es A, B y C.

+0

'cada uno de los números debe ser al menos 2+ el número anterior que imprimieron' Pensé que también, y estaba equivocado :( –

+1

Si t2 avanza más de t1, el' actual' de t2 será mayor que el 'actual' de t1, entonces cuando t1 recupera la CPU de t2, x asumirá la 'corriente' más baja de t1, y esa 'corriente' más baja se imprimirá después de la más alta. Por lo tanto, la salida aún puede bajar. –

+0

He editado mi respuesta. Quise decir es que el número de t1 siempre sube al menos 2 desde lo que t1 imprimió previamente y también el número de t2. – Gray

Cuestiones relacionadas