Algunos comentarios:
.- Nunca debes dejar los catch(Exception) en blanco (se conocen como "blind catches"), ya que entonces nunca sabrás si se produjo un error. Si no los tuvieras, te habrías dado cuenta que el wait() del ThirdThread ya producía una excepción.
.- La excepcion IllegalMonitorStateException se suele producir cuando estas intentando ejecutar un wait/notify sobre un objeto sin tener el acceso sincronizado, lo cual no te deja. Por eso hay que tener sincronizado el acceso cuando se llama a wait()/notify().
.- Al terminar el proceso principal, el programa "se muere" bruscamente, así que hay que tener cuidado con los mensajes que se imprimen justo al final. Puede ser que el tercer Thread termine bien pero no llegues a ver el mensaje por que el programa ha cerrado la salida estandar antes de vaciar el buffer. Por eso le he puesto un sleep() antes de acabar.
.- El programa lo he dejado que funcione, pero no quiere decir que sincronizar directamente sobre el objeto Thread sea lo más recomendable ni lo único que funcione.
.- El interrupt es para interrumpir los Threads bruscamente y lo habitual es usarlo cuando estan en un sleep que quieres cortar. Si estan en un wait se usa notify, que no genera excepciones.
Código PHP:
package test;
public class App
{
public static void main(String[] args) throws InterruptedException
{
System.out.println("Hilo principal " + Thread.currentThread().toString());
FirstThread f = new FirstThread();
ThirdThread t = new ThirdThread();
f.start();
t.start();
f.join();
try
{
synchronized (t)
{
t.notify();
}
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
Thread.sleep(5000);
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println("Fin del padre2");
}
}
class FirstThread extends Thread
{
public void run()
{
try
{
System.out.println(" First thread starts running.");
sleep(5000);
System.out.println(" First thread finishes running.");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
class ThirdThread extends Thread
{
public synchronized void run()
{
try
{
System.out.println(" Third thread starts running.");
wait();
System.out.println(" Third thread finishes running.");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}