Exemplo

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

(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 Dados {
público Dados() {
super();
}
público int getValue() {
retornar valor;
}
público nulo setValue( int valor ) {
esse .value = valor;
}
privado int valor = 0;
}

público estático final class Consumer {
público Consumidor( Dados dados ) {
esse .data = dados;
}

público nulo consumir() {
System.out.println( "Consumidor: consumo foi chamado" ); //$NON-NLS-1$
System.out.println( "Consumidor: autorizando..." ); //$NON-NLS-1$
Thread.yield();
System.out.println( "Consumidor: o valor é " + data.getValue() ); //$NON-NLS-1$
System.out.println( "Consumidor: saindo" ); //$NON-NLS-1$
}

privado Dados dados;
}

público estático final classe Produtor {
público Produtor( Dados dados ) {
esse .data = dados;
}
público nulo produzir() {
System.out.println( "Produtor: a produção foi chamada" ); //$NON-NLS-1$
tentar { Thread.sleep( 3000 ); } capturar (InterruptedException e) {}
data.setValue( 1 );System.out.println( "Produtor: saindo" ); //$NON-NLS-1$
}
privado Dados dados;
}

Solução
Utilize aguardar()/notificar() em vez de autorização().

público estático nulo principal ( Cadeia[] args ) {
Dados dados = novo Dados();
Bloqueio bloqueio = novo Bloqueio();
final Consumidor consumidor = novo Consumidor( dados, bloqueio );
final Produtor produtor = novo Produtor( dados, 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 Dados {
público Dados() {
super();
}
público int getValue() {
retornar valor;
}
público nulo setValue( int valor ) {
esse .value = valor;
}
privado int valor = 0;
}

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( Dados dados, Bloqueio bloqueio ) {
esse .data = dados;
esse .lock = bloqueio;
}

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

privado Dados dados;
privado Bloqueio lock;
}

público estático final classe Produtor {
público Produtor( Dados dados, Bloqueio bloqueio ) {
esse .data = dados;
esse .lock = bloqueio;
}
público nulo produzir() {
System.out.println( "Produtor: a produção foi chamada" ); //$NON-NLS-1$
sincronizado ( bloqueio ) {
tentar { Thread.sleep( 3000 ); } capturar (InterruptedException e) {}
data.setValue( 1 );System.out.println( "Produtor: saindo" ); //$NON-NLS-1$
lock.unlock();
lock.notifyAll();
}
}
privado Dados dados;
privado Bloqueio lock;
}