Tengo 2 matrices y necesito multiplicarlas y luego imprimir los resultados de cada celda. Tan pronto como una celda esté lista, necesito imprimirla, pero, por ejemplo, necesito imprimir la celda [0] [0] antes de la celda [2] [0] incluso si el resultado de [2] [0] está listo primero . Entonces necesito imprimirlo por orden. Entonces, mi idea es hacer que el hilo de la impresora espere hasta que multiplyThread
le notifique que la celda correcta está lista para imprimirse y luego printerThread
imprimirá la celda y volverá a esperar, etc.
Entonces tengo este hilo que hace la multiplicación:
public void run()
{
int countNumOfActions = 0; // How many multiplications have we done
int maxActions = randomize(); // Maximum number of actions allowed
for (int i = 0; i < size; i++)
{
result[rowNum][colNum] = result[rowNum][colNum] + row[i] * col[i];
countNumOfActions++;
// Reached the number of allowed actions
if (countNumOfActions >= maxActions)
{
countNumOfActions = 0;
maxActions = randomize();
yield();
}
}
isFinished[rowNum][colNum] = true;
notify();
}
Hilo que imprime el resultado de cada celda:
public void run()
{
int j = 0; // Columns counter
int i = 0; // Rows counter
System.out.println("The result matrix of the multiplication is:");
while (i < creator.getmThreads().length)
{
synchronized (this)
{
try
{
this.wait();
}
catch (InterruptedException e1)
{
}
}
if (creator.getmThreads()[i][j].getIsFinished()[i][j] == true)
{
if (j < creator.getmThreads()[i].length)
{
System.out.print(creator.getResult()[i][j] + " ");
j++;
}
else
{
System.out.println();
j = 0;
i++;
System.out.print(creator.getResult()[i][j] + " ");
}
}
}
Ahora me arroja estas excepciones:
Exception in thread "Thread-9" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-11" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-10" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-12" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
la línea 49 multiplyThread
es "notificar ()". Creo que necesito usar el sincronizado de manera diferente, pero no estoy seguro de cómo hacerlo.
Si alguien puede ayudar a que este código funcione, realmente lo agradeceré.
fuente
while(!JobCompleted);
opción es generalmente una mala idea porque vincula su CPU al 100% comprobando la misma variable constantemente (ver aquí )while(!JobCompleted) Thread.sleep(5);
no tiene ese problemawait
siempre que el hilo actual tenga un bloqueo en el objeto en el quewait
se llama. Si usa unsynchronized
bloque o un método sincronizado es completamente su decisión .Al usar los métodos
wait
ynotify
onotifyAll
en Java, se deben recordar las siguientes cosas:notifyAll
lugar denotify
si espera que más de un hilo esté esperando un bloqueo.wait
ynotify
deben llamarse en un contexto sincronizado . Vea el enlace para una explicación más detallada.wait()
método en un bucle porque si varios subprocesos esperan un bloqueo y uno de ellos obtuvo el bloqueo y restableció la condición, los otros subprocesos deben verificar la condición después de que se despierten para ver si necesitan esperar nuevamente o puede comenzar a procesar.wait()
ynotify()
método; cada objeto tiene su propia cerradura, por lo que llamarwait()
al objeto A ynotify()
al objeto B no tendrá ningún sentido.fuente
¿Necesitas enhebrar esto? Me pregunto qué tan grandes son sus matrices, y si hay algún beneficio en imprimir un hilo mientras que el otro hace la multiplicación.
¿Quizás valdría la pena medir este tiempo antes de hacer el trabajo de enhebrado relativamente complejo?
Si necesita enhebrarlo, crearía 'n' subprocesos para realizar la multiplicación de las celdas (tal vez 'n' es el número de núcleos disponibles para usted), y luego usaría el mecanismo ExecutorService y Future para despachar múltiples multiplicaciones simultáneamente .
De esa manera, puede optimizar el trabajo en función de la cantidad de núcleos, y está utilizando las herramientas de subprocesamiento Java de nivel superior (que deberían facilitarle la vida). Vuelva a escribir los resultados en una matriz receptora y luego simplemente imprímalo una vez que se hayan completado todas sus tareas futuras.
fuente
Digamos que tiene una aplicación de 'caja negra' con alguna clase llamada
BlackBoxClass
que tiene métododoSomething();
.Además, tiene un observador u oyente llamado
onResponse(String resp)
que será llamadoBlackBoxClass
después de un tiempo desconocido.El flujo es simple:
Digamos que no sabemos qué está sucediendo
BlackBoxClass
y cuándo deberíamos obtener una respuesta, pero no desea continuar su código hasta que obtenga la respuesta o, en otras palabras,onResponse
llame. Aquí ingresa 'Synchronize helper':Ahora podemos implementar lo que queramos:
fuente
Solo puede llamar a notificar sobre los objetos donde posee su monitor. Entonces necesitas algo como
fuente
notify()
necesita ser sincronizado tambiénfuente
Voy a ver un ejemplo simple que te muestra la forma correcta de usar
wait
ynotify
en Java. Así que crearé dos clases llamadas ThreadA y ThreadB . ThreadA llamará a ThreadB.y para la Clase ThreadB:
fuente
Uso simple si quieres Cómo ejecutar hilos alternativamente: -
fuente
podemos llamar a notificar para reanudar la ejecución de objetos en espera como
reanudar esto invocando notificar sobre otro objeto de la misma clase
fuente
Para este problema en particular, ¿por qué no almacenar sus diversos resultados en variables y luego, cuando se procesa el último hilo, puede imprimir en el formato que desee? Esto es especialmente útil si va a utilizar su historial de trabajo en otros proyectos.
fuente
Esto parece una situación para el patrón productor-consumidor. Si está utilizando java 5 o superior, puede considerar el uso de la cola de bloqueo (java.util.concurrent.BlockingQueue) y dejar el trabajo de coordinación del subproceso a la implementación subyacente de framework / api. Vea el ejemplo de java 5: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html o java 7 (mismo ejemplo): http: // docs. oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
fuente
Ha guardado correctamente su bloque de código cuando llama al
wait()
método utilizandosynchronized(this)
.Pero no ha tomado la misma precaución cuando llama al
notify()
método sin usar el bloque protegido:synchronized(this)
osynchronized(someObject)
Si se hace referencia a la página de documentación de Oracle en el objeto de clase, que contiene
wait()
,notify()
,notifyAll()
métodos, se puede ver a continuación precaución en todos estos tres métodosSe han cambiado muchas cosas en los últimos 7 años y veamos otras alternativas a las
synchronized
siguientes preguntas SE:¿Por qué usar un ReentrantLock si uno puede usar sincronizado (esto)?
Sincronización vs bloqueo
¿Evitar sincronizado (esto) en Java?
fuente