não entendo porque esse erro IllegalMonitorStateException

blz pessoal?

Então, estava testando algumas coisas de Threads para me preparar para certificação. Aqui tem um exemplo funcional usando wait, notify e usando bloco sincronizado dentro de um construtor, o que é permitido. Só não pode ter um construtor synchronized. Vejam o código e a saída:

class MinhaThread extends Thread{
    String[] sincronizador;
    
    public MinhaThread(String[] sincronizador) {
        this.sincronizador = sincronizador;
    }
    
    public void run(){
        synchronized(sincronizador){
            while(!sincronizador[0].equals("finish")){
                try{
                    System.out.println("entrou no bloco sincronizado da classe MinhaThread");
                    sincronizador.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
        System.out.println("saiu do modo wait");
    }
}


class Dispara{
    String[] sincronizador = {"sinc"};
    
    Dispara(){
        Thread mt = new MinhaThread(sincronizador);
        mt.start();
        try{
            Thread.sleep(3000);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        synchronized(sincronizador){
            System.out.println("entrou no bloco sinc da classe Dispara");
            sincronizador[0] = "finish";
            sincronizador.notify();
            System.out.println("depois do notify");
        }
    }
}

public class BlocoSincDentroConst {
    public static void main(String args[]){
        System.out.println("main");
        new Dispara();
    }
}

main
entrou no bloco sincronizado da classe MinhaThread
entrou no bloco sinc da classe Dispara
depois do notify
saiu do modo wait
CONSTRUÍDO COM SUCESSO (tempo total: 3 segundos)

Agora se eu modificar o mesmo exemplo acima mudando de um array de String para uma String simples passa a dar erro IllegalMonitorStateException:

[code]class MinhaThread extends Thread{
String sincronizador;

public MinhaThread(String sincronizador) {
    this.sincronizador = sincronizador;
}

public void run(){
    synchronized(sincronizador){
        while(!sincronizador.equals("finish")){
            try{
                System.out.println("entrou no bloco sincronizado da classe MinhaThread");
                sincronizador.wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }
    System.out.println("saiu do modo wait");
}

}

class Dispara{
String sincronizador = “sinc”;

Dispara(){
    Thread mt = new MinhaThread(sincronizador);
    mt.start();
    try{
        Thread.sleep(3000);
    }catch(InterruptedException e){
        e.printStackTrace();
    }
    synchronized(sincronizador){
        System.out.println("entrou no bloco sinc da classe Dispara");
        sincronizador = "finish";
        sincronizador.notify();
        System.out.println("depois do notify");
    }
}

}

public class BlocoSincDentroConst {
public static void main(String args[]){
System.out.println(“main”);
new Dispara();
}
}
[/code]

main
entrou no bloco sincronizado da classe MinhaThread
entrou no bloco sinc da classe Dispara
Exception in thread “main” java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at certificacao.thread.Dispara.(BlocoSincDentroConst.java:50)
at certificacao.thread.BlocoSincDentroConst.main(BlocoSincDentroConst.java:59)
CONSTRUÇÃO PARADA (tempo total: 11 segundos)

Alguém pode me explicar por favor porque funciona com array de String mas não com String?

Obrigado.

            // antes desta linha, a variável "sincronizador" tinha um determinado objeto que era o sendo usado pelo "synchronized"
            sincronizador = "finish";  
            // a linha anterior mudou o objeto, portanto a linha seguinte vai dar problemas:
            sincronizador.notify();  

Conselho: se for usar synchronized, use um Object puro e simples, e não o mude durante a sincronização. Eu costumo usar:

Object lock = new Object();
...
synchronized (lock) {
    ...

Obrigado entanglement, eu havia lida a resposta faz tempo mas não tinha tido tempo de agradecer. Entendi o motivo da exceção. valeu!