Exemplo

público estático nulo principal ( Cadeia[] args ) {
Bloqueio bloqueio = novo Bloqueio();
final Consumidor consumidor = novo Consumidor( bloqueio );
final Produtor produtor = novo Produtor( bloqueio );

(novo Encadeamento( novo Executável() {
público nulo executar() {
consumer.consume();
}
})).start();


(novo Encadeamento( novo Executável() {
público nulo executar() {
producer.produce();
}
})).start();
}

público estático final classe Bloqueio {
público Bloqueio() {
super();
bloqueio();
}
público booleano isAvailable() {
retornar disponível;
}
público nulo bloqueio() {
disponível = falso;
}
público nulo desbloqueio() {
disponível = verdadeiro;
}
privado booleano disponível = falso;
}

público estático final class Consumer {
público Consumidor( Bloqueio bloqueio ) {
esse .lock = bloqueio;
}

público nulo consumir() {
System.out.println( "Consumidor: consumo foi chamado" ); //$NON-NLS-1$
sincronizado ( bloqueio ) {
enquanto ( !lock.isAvailable() ) {
System.out.println( "Consumidor: aguardando..." ); //$NON-NLS-1$
tentar {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumidor: saindo" ); //$NON-NLS-1$
}

privado Bloqueio lock;
}

público estático final classe Produtor {
público Produtor( Bloqueio bloqueio) {
esse .lock = bloqueio;
}
público nulo produzir() {
System.out.println( "Produtor: a produção foi chamada" ); //$NON-NLS-1$
System.out.println( "Produtor: desbloqueando..." ); //$NON-NLS-1$
lock.unlock();
lock.notify();
System.out.println( "Produtor: saindo" ); //$NON-NLS-1$
}
privado Bloqueio lock;
}

Solução
Faça a chamada para java.lang.Object.notify() dentro do bloco sincronizado.

público estático nulo principal ( Cadeia[] args ) {
Bloqueio bloqueio = novo Bloqueio();
final Consumidor consumidor = novo Consumidor( bloqueio );
final Produtor produtor = novo Produtor( bloqueio );

(novo Encadeamento( novo Executável() {
público nulo executar() {
consumer.consume();
}
})).start();


(novo Encadeamento( novo Executável() {
público nulo executar() {
producer.produce();
}
})).start();
}

público estático final classe Bloqueio {
público Bloqueio() {
super();
bloqueio();
}
público booleano isAvailable() {
retornar disponível;
}
público nulo bloqueio() {
disponível = falso;
}
público nulo desbloqueio() {
disponível = verdadeiro;
}
privado booleano disponível = falso;
}

público estático final class Consumer {
público Consumidor( Bloqueio bloqueio ) {
esse .lock = bloqueio;
}

público nulo consumir() {
System.out.println( "Consumidor: consumo foi chamado" ); //$NON-NLS-1$
sincronizado ( bloqueio ) {
enquanto ( !lock.isAvailable() ) {
System.out.println( "Consumidor: aguardando..." ); //$NON-NLS-1$
tentar {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumidor: saindo" ); //$NON-NLS-1$
}
privado Bloqueio lock;
}

público estático final classe Produtor {
público Produtor( Bloqueio bloqueio) {
esse .lock = bloqueio;
}
público nulo produzir() {
System.out.println( "Produtor: a produção foi chamada" ); //$NON-NLS-1$
System.out.println( "Produtor: desbloqueando..." ); //$NON-NLS-1$
sincronizado ( bloqueio ) {
lock.unlock();
lock.notify();
}
System.out.println( "Produtor: saindo" ); //$NON-NLS-1$
}
privado Bloqueio lock;
}