Pergunta

Por que são os wait() e notify() métodos declarados na Object classe, em vez de o Thread classe?

Foi útil?

Solução

Porque você espera em um determinado objeto (ou especificamente, seu monitor) para usar essa funcionalidade.

Eu acho que você pode estar enganado sobre como esses métodos funcionam. Eles não estão simplesmente em um nível de granularidade de roscas, ou seja, é não um caso de apenas ligar wait() e sendo acordado pela próxima chamada para notify(). Em vez disso, você sempre liga wait() em um objeto específico, e só será acordado por chamadas para notify nesse objeto.

Isso é bom porque, de outra forma, as primitivas de concorrência simplesmente não escalavam; Seria equivalente a ter namespaces globais, uma vez que qualquer chamada para notify() Em qualquer lugar do seu programa teria o potencial de estragar tudo algum código simultâneo, pois eles acordariam qualquer tópico bloqueando em um wait() ligar. Daí a razão pela qual você os chama em um objeto específico; Dá um contexto para o par de espera não operar, então quando você liga myBlockingObject.notify(), em um objeto privado, você pode ter certeza de que apenas acordará tópicos que chamavam métodos de espera em sua classe. Algum tópico da primavera que pode estar esperando em outro objeto não será acordado por esta chamada e vice -versa.

Editar: ou para abordá -lo de outra perspectiva - espero da sua pergunta que você pensou que seria um identificador para o tópico de espera e ligar notify() sobre aquele tópico para acordar. A razão pela qual não é feito dessa maneira é que você teria que fazer muita limpeza a si mesmo. O tópico que vai esperar teria que publicar uma referência a si mesma em algum lugar que outros threads poderiam vê -lo; Isso teria que ser sincronizado adequadamente para aplicar a consistência e a visibilidade. E quando você quiser acordar um tópico, você terá que se apossar dessa referência, despertá -lo e removê -lo de onde quer que o leia. Há muito mais andaimes manuais envolvidos e muito mais chances de dar errado com ele (especialmente em um ambiente simultâneo) em comparação com apenas ligar para myObj.wait() no fio adormecido e depois myObj.notify() no tópico Waker.

Outras dicas

A razão mais simples e óbvia é que qualquer objeto (não apenas um thread) pode ser o monitor para um thread. A espera e notificação são chamadas no monitor. O thread em execução verifica com o monitor. Portanto, os métodos de espera e notificação estão em objeto e não thread

Como apenas um thread de cada vez pode possuir o monitor de um objeto e esse monitor é o que os threads estão esperando ou notificando. Se você ler o Javadoc por Object.notify() e Object.wait() é descrito em detalhes.

O mecanismo de sincronização envolve um conceito - monitor de um objeto. Quando Wait () é chamado, o monitor é solicitado e a execução adicional é suspensa até que o monitor seja adquirido ou ocorra o interrupção. Quando notify () é chamado, o monitor é liberado.

Vamos fazer um cenário se espera () e notify () foram colocados na classe de threads em vez da classe de objeto. Em um ponto do código, currentThread.wait() é chamado e depois um objeto anObject é acessado.

//.........
currentThread.wait();
anObject.setValue(1);
//.........

Quando CurrentThread.wait () é chamado, monitor de currentThread é solicitado e nenhuma execução adicional é feita até que o monitor seja adquirido ou ocorra interrupção. Agora enquanto estava em espera, se um método foo() de outro objeto anotherObject residente em currentThread é chamado de outro tópico, está preso, embora o método chamado foo() não acessa anObject. Se o primeiro método wait () foi chamado anObject, em vez do próprio tópico, outros métodos chamam (não acessando anObject) em objetos residentes no mesmo encadeamento não ficariam presos.

Assim, os métodos de chamada wait () e notify () na classe de objeto (ou suas subclasses) fornecem maior concorrência e é por isso que esses métodos estão na classe de objeto, não na classe de threads.

Algumas das outras respostas usam a palavra "monitor", mas nenhuma explica o que isso significa.

O nome "Monitor" foi cunhado na década de 1970 e se referiu a um objeto que tinha sua própria trava intrínseca e o mecanismo de espera/notificação associado. https://en.wikipedia.org/wiki/monitor_%28synchronization%29

Vinte anos depois, houve um breve momento em que os computadores de computadores de computadores e multiprocessadores eram novos, e estava na moda pensar que a maneira certa de projetar software para eles seria criar programas orientados a objetos nos quais cada objeto era um monitor.

Acontece que não foi uma idéia tão útil, mas esse breve momento é exatamente quando a linguagem de programação Java foi inventada.

Ler aqui Para uma explicação de espera e notificar.

Seria melhor evitá -los, no entanto, em seus aplicativos e usar o mais novo java.util.Concurrent pacote.

Vou colocar isso de uma maneira simples:

Para ligar para espera () ou notify (), você precisa possuir o monitor de objeto - isso significa espera () ou notify () precisa estar presente no bloco sincronizado

synchronized(monitorObj){
monitorObj.wait()  or even notify
}

Essa é a razão pela qual esses métodos estão presentes na aula de objeto

Isso ocorre porque esses métodos são para comunicação entre threads e interhreadCommunication ocorre usando bloqueios, mas os bloqueios estão associados a objetos. Portanto, está na classe de objeto.

Aguarde e Notificar métodos são usados na comunicação entre dois Threads em Java.Então, Objeto de classe é o lugar correto para torná-los disponíveis para todos os objetos em Java.

Outra razão é que os Bloqueios são disponibilizados por Objeto base.Threads necessidades de bloqueio e eles esperam para o bloqueio, eles não sabem o que threads mantém bloqueio, em vez disso, eles apenas sabem que o bloqueio é segure por alguns thread e eles devem esperar para bloquear em vez de saber qual o thread dentro do bloco sincronizado e pedindo-lhes para liberação de bloqueio

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top