Exemplo

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

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

(novo Encadeamento( novo Executável() {
público nulo executar() {
consumer2.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, int id ) {
esse .lock = bloqueio;
esse .id = id;
}

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

privado Bloqueio lock;
privado int id;
}

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;
}



Solução
Chame notifyAll() em vez de notificar()

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

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

(novo Encadeamento( novo Executável() {
público nulo executar() {
consumer2.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, int id ) {
esse .lock = bloqueio;
esse .id = id;
}

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

privado Bloqueio lock;
privado int id;
}

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.notifyAll();
}
System.out.println( "Produtor: saindo" ); //$NON-NLS-1$
}
privado Bloqueio lock;
}