Cena de espera não
A cena típica de espera de espera geralmente está relacionada aos dois conteúdos a seguir:
1. Variável de estado
Quando os threads precisam esperar, sempre é causado por algumas condições. Por exemplo, preenchendo a fila, quando o elemento da fila está cheio, o thread precisa parar de funcionar. Quando os elementos da fila estiverem vazios, continue sua própria execução.
2. Predicado da condição
Quando o encadeamento é determinado se a espera ou acorda a partir da notificação, é necessário testar se as condições de status são atendidas. Por exemplo, adicionando elementos à fila, a fila está cheia e bloqueia o thread atual. fio." Neste momento, o processo de espera pelo elemento será despertado e, em seguida, julgará se há realmente espaço para a fila atual. Próximo acordar -up.
3. Fila da condição
Cada objeto possui uma fila de condição construída.
Perceber
Espere e notificar são uma parte importante do mecanismo de sincronização de Java. Combinados com o uso de palavras-chave sincronizadas, muitos modelos síncronos excelentes podem ser estabelecidos, como o modelo do produtor-consumidor. Mas, ao usar a função function (), notify (), notifyAll (), você precisa prestar atenção especial aos seguintes pontos:
Wait (), notify (), notifyAll () Métodos não pertencem à classe Thread, mas pertencem à classe de fundação do objeto, ou seja, cada objeto tem as funções de espera (), notify () e notify (). Como cada objeto está bloqueado, o bloqueio é a base de cada objeto; portanto, o método de operação de bloqueio também é o mais básico.
Ligue para o método Wait () e notify () da Obj, você deve obter o bloqueio OBJ, ou seja, você deve ser escrito no segmento de código sincronizado (obj) {... ...}.
Depois de ligar para obj.wait (), o tópico A libera a fechadura do OBJ, caso contrário, o encadeamento B não pode obter a trava do OBJ e não será capaz de acordar o thread a no sincronizado (obj) {...} código segmento.
Quando o método obj.wait () retornar, o encadeamento A precisa obter o bloqueio do OBJ novamente para continuar a execução.
Se os threads A1, A2, A3 estiverem em obj.wait (), o encadeamento B chama obj.Notify () só poderá acordar um dos threads A1, A2, A3 (que é determinado pela JVM).
Se o thread B chamar obj.NotifyAll (), ele poderá acordar o thread de espera A1, A2, A3, mas o tópico de espera para continuar executando a próxima frase de obj.wait (), você deve obter uma trava obj. Portanto, os threads A1, A2, A3 têm apenas uma chance de obter bloqueios e continuar a executar.
Quando o thread B chama Obj.Notify () ou Obj.NotifyAll (), o Thread B está segurando a trava do OBJ. Até que o thread B saia do bloco de código sincronizado e libere o bloqueio do OBJ, um no thread A1, A2, A3 tem a oportunidade de fazer o bloqueio do objeto e continuar a executar.
Por exemplo, código
A estrutura de código típica da operação de espera do Thread é a seguinte:
public void test () lança interruptedException {sincronizado (obj) {while (! contidition) {obj.wait ();}}}}}}}}}
Por que as operações obj.wait () devem estar localizadas no ciclo? Existem vários motivos principais:
1. Um bloqueio de objeto pode ser usado para proteger várias variáveis de estado. Por exemplo, um determinado objeto bloqueia o OBJ para proteger as duas variáveis de status A e B. Quando as condições de uma afirmação não são estabelecidas, a operação de espera ocorre. Agora, se ocorrer uma operação de uma variável de estado A, a operação notificada é chamada no OBJ, todos os threads na fila de condição correspondentes ao OBJ serão despertados. Para B, também é despertado neste momento, então você precisa reciclar se a condição de B é atendida para ser atendida.
2. As condições do mesmo estado de vários threads são afirmadas. Por exemplo, a cena de adicionar elementos à fila, a fila atual está cheia e vários threads desejam adicionar elementos dentro, para que sejam todos. Nesse momento, outro thread retirou um elemento da fila e chamou a operação NotifyAll para acordar todos os threads, mas apenas um thread poderia adicionar um elemento à fila.
3. Despertar falso. Sem ser notificado, interromper a OROT, o tópico foi automaticamente despertado. Embora essa situação raramente ocorra na prática, essa situação pode ser eliminada através da espera do ciclo.